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

Postgres Convert Rows to Columns based on a Common field Using Crosstab

我有查询 select dist_name::text,service_name::text,status,count from mpr_application_status returns

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

我想要return这样的结果集,我们根据地区名称将行转换为列

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

我已经尝试使用交叉表函数 return 这个想要的 table

SELECT *
FROM   crosstab(
   'select dist_name::text,service_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",0),
coalesce("Reject Count",0),
coalesce("Approved 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