Оптимизация запроса с подсчетом отдельного столбца на основе значения другого столбца

Должен быть лучший способ написать это, но я просто не уверен, что это такое. В основном я пытаюсь подсчитать различные значения из одного столбца, где условие выполняется в отдельном столбце. Я нашел это ссылка, но я не знаю, как ее здесь применить.

Вот запрос, я использую 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

person user1803504    schedule 06.11.2012    source источник


Ответы (1)


Вы можете использовать тот факт, что 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
person lc.    schedule 06.11.2012
comment
Спасибо, но мне нужно рассмотреть все строки, независимо от статуса. Некоторая предыстория: многое зависит от деталей, содержащихся в таблице invdet. Я хочу изучить все детали по любому лоту, хотя бы по одной детали в перечисленных статусах. - person user1803504; 06.11.2012
comment
@user1803504 user1803504 Хорошо, я отредактировал свой ответ, чтобы учесть это. - person lc.; 06.11.2012