Спираючись на інші опубліковані відповіді.
Обидва вони дають правильні значення:
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 був ще набагато дорожчим.
SELECT distributor_id, COUNT(*) AS TOTAL, COUNT(*) WHERE level = 'exec', COUNT(*) WHERE level = 'personal'