加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

postgresql – 在Redshift/Postgres中,如何计数满足条件的行?

发布时间:2020-12-13 16:37:26 所属栏目:百科 来源:网络整理
导读:我正在尝试编写一个仅满足条件的行的查询。 例如,在MySQL中,我将这样写: SELECT COUNT(IF(grade 70),1,NULL)FROM gradesORDER BY id DESC; 但是,当我尝试在Redshift上执行此操作时,它会返回以下错误: 错误:函数if(boolean,integer,“unknown”)不存
我正在尝试编写一个仅满足条件的行的查询。

例如,在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) “。所以,无论哪种情况,你总是得到相同的价值。
SELECT 
    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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读