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
我认为您可以使用 SUM
和 CASE 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
我有查询 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
我认为您可以使用 SUM
和 CASE 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