Aufbauend auf anderen geposteten Antworten.
Beide ergeben die richtigen Werte:
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 ;
Die Leistung ist jedoch sehr unterschiedlich, was offensichtlich mit zunehmender Datenmenge relevanter wird.
Ich stellte fest, dass unter der Annahme, dass keine Indizes für die Tabelle definiert wurden, die Abfrage mit den SUMs einen einzelnen Tabellenscan durchführen würde, während die Abfrage mit den COUNTs mehrere Tabellenscans durchführen würde.
Führen Sie als Beispiel das folgende Skript aus:
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)
Markieren Sie die 2 SELECT-Anweisungen und klicken Sie auf das Symbol "Geschätzten Ausführungsplan anzeigen". Sie werden sehen, dass die erste Anweisung einen Tabellenscan und die zweite 4 ausführt. Offensichtlich ist ein Tabellenscan besser als 4.
Interessant ist auch das Hinzufügen eines Clustered-Index. Z.B
Create clustered index t1f1 on t1(f1);
Update Statistics t1;
Das erste SELECT oben führt einen einzelnen Clustered Index Scan durch. Das zweite SELECT führt 4 Clustered Index-Suchvorgänge durch, die jedoch immer noch teurer sind als ein einzelner Clustered Index-Scan. Ich habe dasselbe an einem Tisch mit 8 Millionen Zeilen versucht und das zweite SELECT war immer noch viel teurer.
SELECT distributor_id, COUNT(*) AS TOTAL, COUNT(*) WHERE level = 'exec', COUNT(*) WHERE level = 'personal'