我在PostgreSQL中有一个表格,如:
org_name | month_1 | month_2 | ... | month_12
---------------------------------------------
org1 | 20 | 30 | ... | 15
org2 | 34 | 27 | ... | 49
我需要将其转置为:
month | org1 | org2
----------------------
1 | 20 | 34
2 | 30 | 27
.. | .. | ..
12 | 15 | 49
我在stackoverflow上找到了下一个解决方案:
SELECT
*
FROM
(select org_name, monthes, value
from my_table
unpivot
(
value
for monthes in (month_2, month_3, month_4, month_5, month_6, month_7, month_8, month_9, month_10, month_11, month_12)
) unpiv
) src
pivot
(
sum(value)
for org_name in ('org1', 'org2')
) piv
但是对于'而言,它并没有处理语法错误。我哪里错了?
答案 0 :(得分:0)
我还没有能够让你的方法工作;但这个多步联盟似乎。
With myTable (org_name, month_1, Month_2, month_3, Month_12) as (
Select 'org1',20,30,40,15 union all
Select 'org2',34,27,45,49),
cte (Mo,Org1,org2) as(select unnest(ARRAY[1,2,3,12]) AS Mo
, case when org_name='org1' then unnest(ARRAY[month_1, Month_2,month_3,Month_12]) end as Org1
, case when org_name='org2' then unnest(ARRAY[month_1, Month_2,month_3,Month_12]) end as Org2
from mytable)
Select mo,sum(org1) org1, sum(org2) org2
From cte
group by mo
也许你会发现更明显的问题:
{{1}}
答案 1 :(得分:0)
实际上,你需要像 plus pivot这样的东西。
1。 将每行分解行以获得单个条目(“unpivot”):
SELECT mon, org_name, val
FROM tbl, LATERAL (
VALUES
(1, month_1)
, (2, month_2)
-- ... more
, (12, month_12)
) x(mon, val)
ORDER BY 1, 2;
如果有更多组织,您必须添加WHERE
子句来选择相关的组:
WHERE org_name IN ('org1', 'org2')
2。 ,将其提供给crosstab()
以获得您想要的结果:
SELECT *
FROM crosstab($$
SELECT mon, org_name, val
FROM tbl, LATERAL (
VALUES
(1, month_1)
, (2, month_2)
-- ... more
, (12, month_12)
) x(mon, val)
WHERE org_name IN ('org1', 'org2')
ORDER BY 1, 2$$)
AS ct (month int, org1 int, org2 int);
VOILÀ。
crosstab()
功能由附加模块 tablefunc
提供,因此必须安装。
详细说明和链接:
这是为任何组织列表和任何月份列表构建SQL语句的基本功能:
CREATE OR REPLACE FUNCTION f_unpivot_colums(_orgs text[], _months int[])
RETURNS text AS
$func$
SELECT 'SELECT *
FROM crosstab($$
SELECT x.mon, t.org_name, x.val
FROM tbl t, LATERAL (
VALUES '
|| string_agg(format('(%s, t.%I)', m, 'month_' || m), ', ')
|| ') x(mon, val)
WHERE t.org_name = ANY (' || quote_literal(_orgs) || ')
ORDER BY 1, 2$$)
AS ct (month int, org1 int, org2 int)'
FROM unnest(_months) m
$func$ LANGUAGE sql;
您也可以动态提取组织或月份列表......
呼叫:
SELECT f_unpivot_colums('{org1, org2}', '{1,2,12}')
生成上述语句 - 您可以依次执行。