2

これを書くにはもっと良い方法があるに違いありませんが、それが何であるかはわかりません。基本的に、別の列で条件が満たされた 1 つの列から個別の値を数えようとしています。このリンクを見つけましたが、ここで適用する方法がわかりません。

これがクエリです。私はSQL Server 2008R2を使用しています

SELECT lot,
    (SELECT COUNT(DISTINCT d.pid) FROM invdet d WHERE upk = 0 and d.lot = [invdet].lot) as noUpk,
    (SELECT COUNT(DISTINCT d.pid) FROM invdet d WHERE upk = 1 and d.lot = [invdet].lot) as isUpk
FROM invdet
WHERE ([status] in ('PQ','P2','FA','F2','BH','RL','SC','LD','PS'))
GROUP BY lot
HAVING COUNT(CASE WHEN invdet.upk = 1 THEN 1 ELSE null END) > 0
4

1 に答える 1

2

COUNT DISTINCTNULL をカウントしないという事実を有利に利用できます。すべての行を調べるWHERE EXISTSには、結果セットをこれらのステータスに限定するのではなく、句を作成します。

SELECT lot,
    COUNT(DISTINCT (CASE WHEN upk = 0 THEN pid ELSE NULL END)) as noUpk
    COUNT(DISTINCT (CASE WHEN upk = 1 THEN pid ELSE NULL END)) as isUpk
FROM invdet q
WHERE EXISTS
(
    SELECT 1 
    FROM invdet i 
    WHERE i.[status] in ('PQ','P2','FA','F2','BH','RL','SC','LD','PS')
    AND i.lot = q.lot
)
GROUP BY lot
HAVING COUNT(CASE WHEN upk = 1 THEN 1 ELSE null END) > 0

HAVING句を句に効果的に移動することもできWHERE EXISTSます。これはより高速であり、次のようになります。

SELECT lot,
    COUNT(DISTINCT (CASE WHEN upk = 0 THEN pid ELSE NULL END)) as noUpk
    COUNT(DISTINCT (CASE WHEN upk = 1 THEN pid ELSE NULL END)) as isUpk
FROM invdet q
WHERE EXISTS
(
    SELECT 1 
    FROM invdet i 
    WHERE i.[status] in ('PQ','P2','FA','F2','BH','RL','SC','LD','PS')
    AND i.lot = q.lot
)
WHERE EXISTS
(
    SELECT 1 
    FROM invdet i 
    WHERE i.upk = 1 
    AND i.lot = q.lot
)
GROUP BY lot
于 2012-11-06T18:06:06.037 に答える