我正在尝试编写一个仅满足条件的行的查询。
例如,在MysqL中,我将这样写:
SELECT COUNT(IF(grade < 70),1,NULL) FROM grades ORDER BY id DESC;
但是,当我尝试在Redshift上执行此操作时,它会返回以下错误:
错误:函数if(boolean,integer,“unknown”)不存在
提示:没有函数与给定的名称和参数类型匹配。您可能需要添加显式类型转换。
我检查了条件语句的文档,我发现
NULLIF(value1,value2)
但它只比较value1和value2,如果这些值相等,则返回null。
我找不到一个简单的IF声明,乍一看,我找不到办法做我想做的事情。
我试图使用CASE表达式,但是我没有得到我想要的结果:
SELECT CASE WHEN grade < 70 THEN COUNT(rank) ELSE COUNT(rank) END FROM grades
这是我想要计数的方式:
>失败(等级<70)
>平均值(70 <=等级<80)
>良好(80 <等级<90)
> 90%=等级(= 100)
这是我期望看到的结果:
+========+=========+======+===========+ | Failed | average | good | excellent | +========+=========+======+===========+ | 4 | 2 | 1 | 4 | +========+=========+======+===========+
但我得到这个:
+========+=========+======+===========+ | Failed | average | good | excellent | +========+=========+======+===========+ | 11 | 11 | 11 | 11 | +========+=========+======+===========+
我希望有人能指出我正确的方向!
如果这有助于这里的一些示例信息
CREATE TABLE grades( grade integer DEFAULT 0,); INSERT INTO grades(grade) VALUES(69,50,55,60,75,70,87,100,98,94);
首先,你所在的问题是你所说的是“如果成绩低于70,这个表达式的值是count(rank),否则,这个表达式的值是count(rank) “。所以,无论哪种情况,你总是得到相同的价值。
原文链接:https://www.f2er.com/postgresql/192984.htmlSELECT CASE WHEN grade < 70 THEN COUNT(rank) ELSE COUNT(rank) END FROM grades
count()仅计算非空值,因此通常您将看到的模式完成您正在尝试的是:
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表达式只有当测试表达式为true时才计算为1,否则为空。那么count()只会计算非空实例,即当测试表达式为真时,哪个应该给你所需要的。
编辑:作为附注,请注意,这与您最初使用count(if(test,true-value,false-value))最初写入的方式完全相同,仅重写为count(当然后为true -value end)(null是false值,因为else没有提供给case)。
编辑: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