Postgres使用交叉表根据公共字段将行转换为列

问题描述

我有返回的查询select dist_name::text,service_name::text,status,count from mpr_application_status

+---------------+--------------+----------------+-------+
| district Name | Service Name | Current Status | Count |
+---------------+--------------+----------------+-------+
| Dehradun      |          143 | APPROVED       |     1 |
| Dehradun      |         143  | PENDING        |     2 |
+---------------+--------------+----------------+-------+

我想返回这样的结果集,其中我们将根据地区名称将行转换为列

+---------------+--------------+---------------+----------------+----------------+-------------+
| district Name | Service Name | ApprovedCount | Rejected Count | Pending  Count | Total Count |
+---------------+--------------+---------------+----------------+----------------+-------------+
| Dehradun      |          143 |             1 |              0 |              2 |           3 |
+---------------+--------------+---------------+----------------+----------------+-------------+

我尝试使用交叉表函数返回此所需的表

SELECT *
FROM   crosstab(
   'select dist_name::text,count from mpr_application_status ORDER BY 1,2') 
   AS ct ("district Name" text,"Service Name" text,"Approved Count" bigint,"Pending Count" bigint,"Reject Count" bigint);
 

但是遇到错误

ERROR:  return and sql tuple descriptions are incompatible
sql state: 42601

有什么办法可以在数据库端实现此结果? 我正在使用postgresql 10

解决方法

我认为您可以使用SUMCASE WHEN来做到这一点:

SELECT dist_name::text,service_name::text,SUM(case when status = 'APPROVED' then count else 0 end) approved_count,SUM(case when status = 'REJECTED' then count else 0 end) rejected_count,SUM(case when status = 'PENDING' then count else 0 end) pending_count,SUM(count) as total_count
FROM mpr_application_status
GROUP BY dist_name,service_name
,

您使用的crosstab()格式将与您期望的输出不符。您应该这样写:

SELECT 
"District Name","Service Name",coalesce("Approved Count",0),coalesce("Pending Count",coalesce("Reject Count",0)+coalesce("Pending Count",0)+coalesce("Reject Count",0) "Total"
FROM   
crosstab(
'select dist_name::text "District Name",service_name::text "Service Name",status,count 
from mpr_application_status ORDER BY 1,2','select ''APPROVED'' union select ''PENDING'' union select ''REJECTED'' ') 
AS ct ("District Name" text,"Service Name" text,"Approved Count" bigint,"Pending Count" bigint,"Reject Count" bigint);
 

您也可以使用filter子句来完成

select 
dist_name,service_name,sum("count") filter (where status='Approved') "Approved Count",sum("count") filter (where status='Pending') "Pending Count",sum("count") filter (where status='Rejected') "Rejected Count",sum("count")

from mpr_application_status
group by 1,2

DEMO

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...