1

最近、行のカウントに関する問題に遭遇しました。

私が使用しているテーブルには多くの記事があり、それぞれがムーブメントに関連付けられており、ムーブメントはユーザーに属しています。通常、各ユーザーの異なる動きの数を数えるには、次のようにします。

SELECT Mov.Usuario, COUNT(DISTINCT Mov.MovID)
FROM Mov
WHERE Mov.Mov = 'Requisicion'
GROUP BY Mov.Usuario

これにより、次のようなテーブルが得られます。

ここに画像の説明を入力

ただし、このテーブルには、各記事のデータとムーブメントの ID も含める必要があります。たとえば、次のようになります。

ここに画像の説明を入力

ユーザー CGARCIA の行のみを表示するように結果をトリミングしました

3 番目の列を取得するには、他のテーブルと結合する必要があったため、最初の 3 列を取得するために、次のクエリを実行しました。

SELECT Mov.Usuario, Mov.MovID, Art.Descripcion1
FROM Mov
INNER JOIN CompraD
ON Mov.ID = CompraD.ID
INNER JOIN Art
ON CompraD.Articulo = Art.Articulo
WHERE Mov.Mov = 'Requisicion'

問題は、各ユーザーの異なる MovID の数をカウントする 4 番目の列を取得するにはどうすればよいかということです。SELECT部分の最後にCOUNT (DISTINCT Mov.MovID)を追加しようとして、クエリの最後にGROUP BY Mov.MovIDを追加すると、次のようなエラーがスローされます。

"選択リストの列 'Mov.MovID' は有効ではありません。集計関数に含まれていないか、"

はい、こんな感じで途中で切れます。

追加の問題として、この SQL ステートメントは外部プログラムから呼び出されることを意図しており、結果を日付でフィルタリングできます。そのために、開始日と終了日を尋ねるフォームを表示し、次のようにクエリの最後にWHERE条件を追加します。

SELECT Mov.Usuario, Mov.MovID, Art.Descripcion1
FROM Mov
INNER JOIN CompraD
ON Mov.ID = CompraD.ID
INNER JOIN Art
ON CompraD.Articulo = Art.Articulo
WHERE Mov.Mov = 'Requisicion'
AND Mov.FechaEmision BETWEEN 'ParameterA' AND 'ParameterB' -- This is the line added by the system

これを制御することはできません。パラメーターはプログラムによって書き込まれるため、クエリに追加することもできません。ただし、条件の後にプログラムにGROUP BYを最後に追加させることはできます。

データの入ったテーブルを取得して、行の入ったテーブルと結合するなどしてみましたが、プログラムが最後にフィルター条件を追加するため、カウント結果には影響せず、すべての行をカウントします。

どうすればこれを回避できますか?

4

2 に答える 2

1

これを試して:

SELECT Mov.Usuario, Mov.MovID, Art.Descripcion1, cntMov.CountCol
FROM Mov m1
INNER JOIN CompraD c ON m1.ID = c.ID
INNER JOIN Art a ON c.Articulo = a.Articulo
OUTER APPLY 
(
   SELECT COUNT(DISTINCT x.MovID) CountCol
   FROM Mov x
   WHERE x.Mov = m1.Mov
   GROUP BY x.Usuario
) cntMov
WHERE m1.Mov = 'Requisicion'
AND m1.FechaEmision BETWEEN 'ParameterA' AND 'ParameterB'

編集: 

SELECT Mov.Usuario, Mov.MovID, Art.Descripcion1,  
COUNT(*) OVER (PARTITION BY Mov.Usuario) Cnt
FROM Mov m1
INNER JOIN CompraD c ON m1.ID = c.ID
INNER JOIN Art a ON c.Articulo = a.Articulo   
WHERE m1.Mov = 'Requisicion'
AND m1.FechaEmision BETWEEN 'ParameterA' AND 'ParameterB'
于 2013-05-15T19:06:08.160 に答える
0

DISTINCT の問題を処理するには、これを試してください (Plamen Ratchev のアイデア):

WITH MovRanked AS (
  SELECT
    Mov.Usuario, Mov.MovID, Art.Descripcion1,
    DENSE_RANK() OVER (
      PARTITION BY Mov.Usario
      ORDER BY Mov.MovID
    ) AS rk
  FROM Mov m1
  INNER JOIN CompraD c ON m1.ID = c.ID
  INNER JOIN Art a ON c.Articulo = a.Articulo   
  WHERE m1.Mov = 'Requisicion'
  AND m1.FechaEmision BETWEEN 'ParameterA' AND 'ParameterB'
)
  SELECT
    Usario, MovID, Descripcion1,
    MAX(rk) over (PARTITION BY Usario) as MovIDcount
  FROM MovRanked
于 2013-05-16T17:44:21.487 に答える