unpivot and PostgreSQL

匿名 (未验证) 提交于 2019-12-03 02:06:01

问题:

Is there a unpivot equivalent function in PostgreSQL?

回答1:

Create an example table:

CREATE TEMP TABLE foo (id int, a text, b text, c text); INSERT INTO foo VALUES (1, 'ant', 'cat', 'chimp'), (2, 'grape', 'mint', 'basil'); 

You can 'unpivot' or 'uncrosstab' using UNION ALL:

SELECT id,        'a' AS colname,        a AS thing FROM foo UNION ALL SELECT id,        'b' AS colname,         b AS thing FROM foo UNION ALL SELECT id,         'c' AS colname,        c AS thing FROM foo ORDER BY id; 

This runs 3 different subqueries on foo, one for each column we want to unpivot, and returns, in one table, every record from each of the subqueries.

But that will scan the table N times, where N is the number of columns you want to unpivot. This is inefficient, and a big problem when, for example, you're working with a very large table that takes a long time to scan.

Instead, use:

SELECT id,        unnest(array['a', 'b', 'c']) AS colname,        unnest(array[a, b, c]) AS thing FROM foo ORDER BY id; 

This is easier to write, and it will only scan the table once.

array[a, b, c] returns an array object, with the values of a, b, and c as it's elements. unnest(array[a, b, c]) breaks the results into one row for each of the array's elements.

Hope that helps!



回答2:

FYI for those of us looking for how to unpivot in RedShift.

The long form solution given by Stew appears to be the only way to accomplish this.

https://forums.aws.amazon.com/thread.jspa?threadID=126369


For those who cannot see it there here is the text pasted below...

We do not have built-in functions that will do pivot or unpivot. However, you can always write SQL to do that.

create table sales (regionid integer, q1 integer, q2 integer, q3 integer, q4 integer); insert into sales values (1,10,12,14,16), (2,20,22,24,26);  select * from sales order by regionid;  regionid | q1 | q2 | q3 | q4 ----------+----+----+----+---- 1 | 10 | 12 | 14 | 16 2 | 20 | 22 | 24 | 26  (2 rows) 

pivot query

create table sales_pivoted (regionid, quarter, sales) as select regionid, 'Q1', q1 from sales UNION ALL select regionid, 'Q2', q2 from sales UNION ALL select regionid, 'Q3', q3 from sales UNION ALL select regionid, 'Q4', q4 from sales ;  select * from sales_pivoted order by regionid, quarter;  regionid | quarter | sales  ----------+---------+------- 1 | Q1 | 10 1 | Q2 | 12 1 | Q3 | 14 1 | Q4 | 16 2 | Q1 | 20 2 | Q2 | 22 2 | Q3 | 24 2 | Q4 | 26 (8 rows) 

unpivot query

select regionid, sum(Q1) as Q1, sum(Q2) as Q2, sum(Q3) as Q3, sum(Q4) as Q4 from (select regionid,  case quarter when 'Q1' then sales else 0 end as Q1, case quarter when 'Q2' then sales else 0 end as Q2, case quarter when 'Q3' then sales else 0 end as Q3, case quarter when 'Q4' then sales else 0 end as Q4 from sales_pivoted)  group by regionid order by regionid; regionid | q1 | q2 | q3 | q4  ----------+----+----+----+---- 1 | 10 | 12 | 14 | 16 2 | 20 | 22 | 24 | 26 (2 rows) 

Hope this helps, Neil



回答3:

I wrote a horrible unpivot function for PostgreSQL. It's rather slow but it at least returns results like you'd expect an unpivot operation to.

https://cgsrv1.arrc.csiro.au/blog/2010/05/14/unpivotuncrosstab-in-postgresql/

Hopefully you can find it useful..



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!