Основываясь на других опубликованных ответах.
Оба они дадут правильные значения:
select distributor_id,
count(*) total,
sum(case when level = 'exec' then 1 else 0 end) ExecCount,
sum(case when level = 'personal' then 1 else 0 end) PersonalCount
from yourtable
group by distributor_id
SELECT a.distributor_id,
(SELECT COUNT(*) FROM myTable WHERE level='personal' and distributor_id = a.distributor_id) as PersonalCount,
(SELECT COUNT(*) FROM myTable WHERE level='exec' and distributor_id = a.distributor_id) as ExecCount,
(SELECT COUNT(*) FROM myTable WHERE distributor_id = a.distributor_id) as TotalCount
FROM myTable a ;
Однако производительность сильно отличается, что, очевидно, будет более актуальным по мере роста количества данных.
Я обнаружил, что при условии, что в таблице не определены индексы, запрос с использованием SUM будет выполнять сканирование одной таблицы, а запрос с COUNT - несколько сканирований таблиц.
В качестве примера запустите следующий скрипт:
IF OBJECT_ID (N't1', N'U') IS NOT NULL
drop table t1
create table t1 (f1 int)
insert into t1 values (1)
insert into t1 values (1)
insert into t1 values (2)
insert into t1 values (2)
insert into t1 values (2)
insert into t1 values (3)
insert into t1 values (3)
insert into t1 values (3)
insert into t1 values (3)
insert into t1 values (4)
insert into t1 values (4)
insert into t1 values (4)
insert into t1 values (4)
insert into t1 values (4)
SELECT SUM(CASE WHEN f1 = 1 THEN 1 else 0 end),
SUM(CASE WHEN f1 = 2 THEN 1 else 0 end),
SUM(CASE WHEN f1 = 3 THEN 1 else 0 end),
SUM(CASE WHEN f1 = 4 THEN 1 else 0 end)
from t1
SELECT
(select COUNT(*) from t1 where f1 = 1),
(select COUNT(*) from t1 where f1 = 2),
(select COUNT(*) from t1 where f1 = 3),
(select COUNT(*) from t1 where f1 = 4)
Выделите 2 оператора SELECT и щелкните значок «Показать предполагаемый план выполнения». Вы увидите, что первый оператор выполнит одно сканирование таблицы, а второй - 4. Очевидно, что одно сканирование таблицы лучше, чем 4.
Также интересно добавить кластерный индекс. Например.
Create clustered index t1f1 on t1(f1);
Update Statistics t1;
Первый SELECT выше выполнит одно сканирование кластерного индекса. Второй SELECT выполнит 4 поиска по кластеризованному индексу, но они по-прежнему дороже, чем одно сканирование по кластеризованному индексу. Я попробовал то же самое с таблицей с 8 миллионами строк, и второй SELECT все еще был намного дороже.
person
Kevin Balmforth
schedule
03.12.2015
SELECT distributor_id, COUNT(*) AS TOTAL, COUNT(*) WHERE level = 'exec', COUNT(*) WHERE level = 'personal'
- person Pratik   schedule 13.03.2016