Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 基于其他列值的具有不同列计数的查询优化_Sql_Sql Server - Fatal编程技术网

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

Sql 基于其他列值的具有不同列计数的查询优化,sql,sql-server,Sql,Sql Server,一定有更好的方法写这个,但我不确定那是什么。基本上,我试图从一列中计算不同的值,其中一个条件在单独的列中得到满足。我发现了这个,但不知道如何在这里应用它 这里是查询,我使用的是SQLServer2008R2 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) FR

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

这里是查询,我使用的是SQLServer2008R2

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

您可以利用
COUNT DISTINCT
不计算空值这一事实来为您带来好处。为了检查所有行,请创建一个
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

谢谢,但是我需要考虑所有的行,不管状态如何。一些背景:很多是invdet表中包含的详细信息的父项。我想检查列出状态中至少有一个详细信息的任何批次的所有详细信息。@user1803504好的,我已经编辑了我的答案以考虑到这一点。