在 SQL 中将列反转为行
Posted
技术标签:
【中文标题】在 SQL 中将列反转为行【英文标题】:Unpivot columns into rows in SQL 【发布时间】:2021-05-08 08:35:10 【问题描述】:我有一张类似如下的表格:
date customer shop view add buy
01/01/21 tim abc 10 5 1
01/01/21 anna abc 2 2 2
02/01/21 anna hnm 5 4 3
我想要的输出如下表:
date customer shop activity value
01/01/21 tim abc view 10
01/01/21 tim abc add 5
01/01/21 tim abc buy 1
01/01/21 anna abc view 2
01/01/21 anna abc add 2
01/01/21 anna abc buy 2
02/01/21 anna hnm view 5
02/01/21 anna hnm add 4
02/01/21 anna hnm buy 3
我想取消透视表,但我不确定最好的方法是什么? UNNEST() 是正确的方法吗?这是我尝试过的查询,但它不起作用:
SELECT date,
customer,
shop,
UNNEST(ARRAY['view', 'add', 'buy']) AS activity
UNNEST(ARRAY[view, add, buy]) AS value
FROM table
GROUP BY date, customer, shop
如果您能给我任何建议,我们将不胜感激。
【问题讨论】:
【参考方案1】:在 Redshift 中,union all
可能是最简单的方法:
select date, customer, shop, 'view' as activity, view as value
from t
union all
select date, customer, shop, 'add' as activity, add as value
from t
union all
select date, customer, shop, 'buy' as activity, buy as value
from t;
您还可以使用case
和cross join
进行反透视:
select t.date, t.customer, t.shop, x.activity,
(case x.activity when 'view' then t.view when 'add' then t.add when 'buy' then t.buy end) as value
from t cross join
(select 'view' as activity union all
select 'add' as activity union all
select 'buy' as activity
) x;
请注意,聚合不是必需的。
【讨论】:
感谢您的精彩提示,我不知道在这种情况下也可以使用 UNION ALL @tlqn 。 . .我确实认为这是更好的答案,因为不需要聚合来做你想做的事。 感谢@GordonLinoff 的精彩回答,只是想知道如何使用枢轴 @pc_pyr 。 . . Redshift 不支持pivot
。【参考方案2】:
我认为您在这里不需要任何非标准 SQL,只需要交叉连接和一些条件聚合:
select
date, customer, shop, activity
, max(case when activity = 'view' then view
when activity = 'add' then add
when activity = 'buy' then buy end) as value
from mytable
cross join (
select 'view' as activity union all
select 'add' union all
select 'buy'
) d
group by
date, customer, shop, activity
order by
date, customer, shop, activity
产生以下结果:
date | customer | shop | activity | value
------------|----------|------|----------|-------
2021-01-01 | anna | abc | add | 2
2021-01-01 | anna | abc | buy | 2
2021-01-01 | anna | abc | view | 2
2021-01-01 | tim | abc | add | 5
2021-01-01 | tim | abc | buy | 1
2021-01-01 | tim | abc | view | 10
2021-01-02 | anna | hnm | add | 4
2021-01-02 | anna | hnm | buy | 3
2021-01-02 | anna | hnm | view | 5
基于 Postgres 的演示 here
【讨论】:
以上是关于在 SQL 中将列反转为行的主要内容,如果未能解决你的问题,请参考以下文章