/ / Otimização de consulta com contagens de coluna distinta com base no valor de outra coluna - sql, sql-server

Otimização de consulta com contagens de colunas distintas com base no valor de outra coluna - sql, sql-server

Deve haver uma maneira melhor de escrever isso, mas eu estousó não tenho certeza do que é isso. Basicamente, estou tentando contar os valores distintos de uma coluna em que uma condição é atendida em uma coluna separada. ligação, mas não sei como aplicá-lo aqui.

Aqui está a consulta, estou usando o 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

Respostas:

2 para resposta № 1

Você pode usar o fato de que COUNT DISTINCT não conta NULLs para sua vantagem. Para examinar todas as linhas, crie um WHERE EXISTS , em vez de limitar seu conjunto de resultados a esses status:

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

Você também pode mover efetivamente o HAVING cláusula em um WHERE EXISTS também, que pode ser mais rápida, resultando em:

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