基于其他列的值优化具有不同列的计数的查询

时间:2012-11-06 18:01:16

标签: sql sql-server

必须有一个更好的方法来写这个,但我只是不确定那是什么。基本上我试图在一个单独的列中计算满足条件的一列中的不同值。我发现了这个link,但我不确定如何在这里应用它。

这是查询,我正在使用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

1 个答案:

答案 0 :(得分:2)

您可以使用COUNT DISTINCT不计算NULL的事实。要检查所有行,请创建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