sql - 基于其他列的值的不同列计数优化查询

标签 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

最佳答案

您可以利用 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

关于sql - 基于其他列的值的不同列计数优化查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13256685/

相关文章:

sql - postgreSQL 解释分析函数

sql - 在 msdb.dbo.sysssispackages XML 中查询特定值

sql - 在 Sqlite 的 Insert 命令中调用用户定义的函数

mysql - 创建表时 Java SQL 语法错误

SQL 智能连接

sql - 在ORDER BY中使用SQL串联

sql - 在 SQL Server 2005 中设置和重置日期格式

sql-server - 主键的 Sql 数据类型 - SQL Server?

php - MySql 查询两张表

c# - Log4Net AdoNetAppender- 截断表/删除旧记录/限制 DB 大小