Postgres 交叉表查询动态数据透视表
Postgres Crosstab query Dynamic pivot
有人知道如何在 Postgres 中创建以下交叉表吗?
例如我有以下 table:
Store Month Sales
A Mar-2020 100
A Feb-2020 200
B Mar-2020 400
B Feb-2020 500
A Jan-2020 400
C Apr-2020 600
我想查询 return 以下交叉表,列标题不应是硬编码值,而是反映第一个 table 的 "month" 列中的值:
Store Jan-2020 Feb-2020 Mar-2020 Apr-2020
A 400 200 100 -
B - 500 400 -
C - - - 600
这可能吗?
尝试在 SUM()
中使用 CASE
表达式,这里是 db-fiddle.
select
store,
sum(case when month = 'Jan-2020' then sales end) as "Jan-2020",
sum(case when month = 'Feb-2020' then sales end) as "Feb-2020",
sum(case when month = 'Mar-2020' then sales end) as "Mar-2020",
sum(case when month = 'Apr-2020' then sales end) as "Apr-2020"
from myTable
group by
store
order by
store
输出:
+---------------------------------------------------+
|store Jan-2020 Feb-2020 Mar-2020 Apr-2020|
+---------------------------------------------------+
| A 400 200 100 null |
| B null 500 400 null |
| C null null null 600 |
+---------------------------------------------------+
如果要在输出中用 0
替换 null
值,请使用 coalesce()
例如
coalesce(sum(case when month = 'Jan-2020' then sales end), 0)
Postgres 确实有一个 crosstab
函数,但我认为在这种情况下使用内置的过滤功能很简单:
select store,
sum(sales) filter (where month = 'Jan-2020') as Jan_2020,
sum(sales) filter (where month = 'Feb-2020') as Feb_2020,
sum(sales) filter (where month = 'Mar-2020') as Mar_2020,
sum(sales) filter (where month = 'Apr-2020') as Apr_2020
from t
group by store
order by store;
注意:这会将 NULL
个值放在没有对应值的列中,而不是 -
。如果您真的想要连字符,则需要将值转换为字符串——这似乎不必要地复杂。
有人知道如何在 Postgres 中创建以下交叉表吗?
例如我有以下 table:
Store Month Sales
A Mar-2020 100
A Feb-2020 200
B Mar-2020 400
B Feb-2020 500
A Jan-2020 400
C Apr-2020 600
我想查询 return 以下交叉表,列标题不应是硬编码值,而是反映第一个 table 的 "month" 列中的值:
Store Jan-2020 Feb-2020 Mar-2020 Apr-2020
A 400 200 100 -
B - 500 400 -
C - - - 600
这可能吗?
尝试在 SUM()
中使用 CASE
表达式,这里是 db-fiddle.
select
store,
sum(case when month = 'Jan-2020' then sales end) as "Jan-2020",
sum(case when month = 'Feb-2020' then sales end) as "Feb-2020",
sum(case when month = 'Mar-2020' then sales end) as "Mar-2020",
sum(case when month = 'Apr-2020' then sales end) as "Apr-2020"
from myTable
group by
store
order by
store
输出:
+---------------------------------------------------+
|store Jan-2020 Feb-2020 Mar-2020 Apr-2020|
+---------------------------------------------------+
| A 400 200 100 null |
| B null 500 400 null |
| C null null null 600 |
+---------------------------------------------------+
如果要在输出中用 0
替换 null
值,请使用 coalesce()
例如
coalesce(sum(case when month = 'Jan-2020' then sales end), 0)
Postgres 确实有一个 crosstab
函数,但我认为在这种情况下使用内置的过滤功能很简单:
select store,
sum(sales) filter (where month = 'Jan-2020') as Jan_2020,
sum(sales) filter (where month = 'Feb-2020') as Feb_2020,
sum(sales) filter (where month = 'Mar-2020') as Mar_2020,
sum(sales) filter (where month = 'Apr-2020') as Apr_2020
from t
group by store
order by store;
注意:这会将 NULL
个值放在没有对应值的列中,而不是 -
。如果您真的想要连字符,则需要将值转换为字符串——这似乎不必要地复杂。