PostgreSQL GROUP BY实现单字段转多统计列的查询求助
PostgreSQL查询修正:按Payor统计事件状态及数量
现有表结构及数据
表名:tbl
| Payor | Event_id | event_Status |
|---|---|---|
| canada | 100 | show |
| greenland | 200 | no show |
| canada | 300 | no show |
| Italy | 400 | show |
需求结果
需要按Payor分组,统计以下信息:
- 该Payor的唯一事件ID总数
- 状态为
show的事件数量 - 状态为
no show的事件数量
结果格式:
| Payor | count(distinct Event_id) | count(event_Status=show) | count(event_Status=no show) |
|---|---|---|---|
| canada | 2 | 1 | 1 |
| greenland | 1 | 0 | 1 |
| Italy | 1 | 1 | 0 |
原查询问题分析
你的查询存在几个关键问题:
- 表名拼写错误:原表名为
tbl,但子查询里写成了tabl,导致无法定位目标表。 - 大小写不匹配:PostgreSQL默认区分大小写,表中
event_Status的值是小写的show/no show,但查询里用了like 'Show%'/like 'No Show%',无法匹配到数据。 - 子查询逻辑错误:子查询中使用
group by payor会返回多行结果,作为标量子查询会引发语法错误;同时子查询未关联主查询的payor,无法实现按单个Payor统计。 - 统计逻辑不符需求:需求中第一个统计项是每个Payor的总唯一事件ID数,而原查询子查询只统计了特定状态下的数量,不符合要求。
修正后的查询语句
使用PostgreSQL的条件聚合可以简洁实现需求,无需嵌套子查询:
SELECT payor, COUNT(DISTINCT event_id) AS "count(distinct Event_id)", SUM(CASE WHEN event_status = 'show' THEN 1 ELSE 0 END) AS "count(event_Status=show)", SUM(CASE WHEN event_status = 'no show' THEN 1 ELSE 0 END) AS "count(event_Status=no show)" FROM tbl GROUP BY payor ORDER BY payor;
语句说明
COUNT(DISTINCT event_id):统计每个Payor的唯一事件ID总数。SUM(CASE ...):通过条件判断,分别统计show和no show状态的事件数量,符合条件则加1,否则加0,求和后得到对应状态的计数。GROUP BY payor:按Payor分组,确保每个Payor只返回一行统计结果。
内容的提问来源于stack exchange,提问作者Rahul Dev vasisht
相关产品推荐
相关产品推荐

