PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Wie werden in Redshift/Postgres Zeilen gezählt, die eine Bedingung erfüllen?

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