Erstens ist das Problem, das Sie hier haben, dass Sie sagen:„Wenn die Note weniger als 70 beträgt, ist der Wert dieses Fallausdrucks count(rank). Andernfalls ist der Wert dieses Ausdrucks count(rank). ." Sie erhalten also in beiden Fällen immer denselben Wert.
SELECT
CASE
WHEN grade < 70 THEN COUNT(rank)
ELSE COUNT(rank)
END
FROM
grades
count() zählt nur Nicht-Null-Werte, also ist das typische Muster, das Sie sehen werden, um das zu erreichen, was Sie versuchen, dieses:
SELECT
count(CASE WHEN grade < 70 THEN 1 END) as grade_less_than_70,
count(CASE WHEN grade >= 70 and grade < 80 THEN 1 END) as grade_between_70_and_80
FROM
grades
Auf diese Weise wird der case-Ausdruck nur dann zu 1 ausgewertet, wenn der Testausdruck wahr ist, und ansonsten null sein. Dann zählt count() nur die Nicht-Null-Instanzen, d. h. wenn der Testausdruck wahr ist, was Ihnen das geben sollte, was Sie brauchen.
Bearbeiten:Beachten Sie als Randnotiz, dass dies genau das gleiche ist, wie Sie es ursprünglich mit count(if(test, true-value, false-value))
geschrieben hatten , nur umgeschrieben als count(case when test then true-value end)
(und null ist der falsche Wert seit einem else
wurde dem Koffer nicht beigelegt).
Bearbeiten:Postgres 9.4 wurde einige Monate nach diesem ursprünglichen Austausch veröffentlicht. Diese Version führte Aggregatfilter ein, die Szenarien wie dieses ein wenig schöner und klarer aussehen lassen können. Diese Antwort wird immer noch gelegentlich positiv bewertet. Wenn Sie also hierher gestoßen sind und ein neueres Postgres (z. B. 9.4+) verwenden, sollten Sie diese äquivalente Version in Betracht ziehen:
SELECT
count(*) filter (where grade < 70) as grade_less_than_70,
count(*) filter (where grade >= 70 and grade < 80) as grade_between_70_and_80
FROM
grades