他の投稿された回答に基づいて構築します。
これらはどちらも正しい値を生成します。
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ステートメントを強調表示し、[推定実行プランの表示]アイコンをクリックします。最初のステートメントは1つのテーブルスキャンを実行し、2番目のステートメントは4を実行することがわかります。明らかに、1つのテーブルスキャンは4よりも優れています。
クラスタ化インデックスを追加することも興味深いです。例えば
Create clustered index t1f1 on t1(f1);
Update Statistics t1;
上記の最初のSELECTは、単一のクラスター化インデックススキャンを実行します。2番目のSELECTは4つのクラスター化インデックスシークを実行しますが、1つのクラスター化インデックススキャンよりもコストがかかります。800万行のテーブルで同じことを試しましたが、2番目のSELECTの方がはるかに高価でした。
SELECT distributor_id, COUNT(*) AS TOTAL, COUNT(*) WHERE level = 'exec', COUNT(*) WHERE level = 'personal'