まず、ここで問題になっているのは、「グレードが70未満の場合、このケース式の値はcount(rank)です。それ以外の場合、この式の値はcount(rank)です。 。」したがって、どちらの場合でも、常に同じ値が得られます。
SELECT
CASE
WHEN grade < 70 THEN COUNT(rank)
ELSE COUNT(rank)
END
FROM
grades
count()はnull以外の値のみをカウントするため、通常、試行していることを達成するために表示されるパターンは次のとおりです。
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
そうすれば、case式はtest式がtrueの場合にのみ1と評価され、それ以外の場合はnullになります。次に、count()は、null以外のインスタンスのみをカウントします。つまり、テスト式がtrueの場合、必要なものが得られるはずです。
編集:補足として、これはcount(if(test, true-value, false-value))
を使用して最初にこれを記述した方法とまったく同じであることに注意してください。 、count(case when test then true-value end)
としてのみ書き直されます (そしてnullはelse
以来のfalse-valueの略です ケースに供給されませんでした。
編集:postgres 9.4は、この最初の交換の数か月後にリリースされました。そのバージョンでは、集約フィルターが導入されました。これにより、このようなシナリオが少し見栄えが良くなります。この回答にはまだ時折賛成票が寄せられているため、ここで偶然見つけて新しいpostgres(つまり、9.4以降)を使用している場合は、この同等のバージョンを検討することをお勧めします。
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