将列逆透视为 SQL 中的行

Unpivot columns into rows in SQL

我有一个table类似如下:

  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             

我想要的输出如下 table:

  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   

我想反转 table,但我不确定最好的方法是什么? 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 

如果您能给我任何建议,我们将不胜感激。

我认为您在这里不需要任何非标准 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

在 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;

您也可以使用 casecross 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;

请注意,聚合不是必需的。