从雪花中的表中取消嵌套

问题描述

我有下表:

PersonID    CW_MilesRun    PW_MilesRun    CM_MilesRun    PM_MilesRun
1           15             25             35             45         
2           10             20             30             40         
3           5              10             15             20         
...

我需要将此表拆分为一个垂直表,每个字段都有一个 id(即 CD_MilesRun =1、CW_MilesRun = 2 等),以便我的表看起来像这样:

PersonID    TimeID    Description    C_MilesRun    P_MilesRun
1           1         Week           15            25
1           2         Month          35            45
2           1         Week           10            20
2           2         Month          30            40
3           1         Week           5             10
3           2         Month          15            20

在 postgres 中,我会使用类似于:

SELECT
    PersonID,unnest(array[1,2]) AS TimeID,unnest(array['Week','Month']) AS "Description",unnest(array["CW_MilesRun","CM_MilesRun"]) C_MilesRun,unnest(array["PW_MilesRun","PM_MilesRun"]) P_MilesRun
FROM myTableHere
;

但是,我无法在雪花中使用类似的功能。有什么想法吗?

解决方法

您可以将 FLATTEN()LATERAL 结合使用以获得您想要的结果,尽管查询完全不同。

with tbl as (select $1 PersonID,$2   CW_MilesRun,$3    PW_MilesRun,$4   CM_MilesRun,$5    PM_MilesRun from values (1,15,25,35,45),(2,10,20,30,40),(3,5,20))

select
    PersonID,t.value[0] TimeID,t.value[1] Description,iff(t.index=0,CW_MilesRun,CM_MilesRun) C_MilesRun,iff(t.index=1,PW_MilesRun,PM_MilesRun) P_MilesRun
from tbl,lateral flatten(parse_json('[[1,"Week"],[2,"Month"]]')) t;

PERSONID    TIMEID  DESCRIPTION C_MILESRUN  P_MILESRUN
1   1   "Week"  15  25
1   2   "Month" 35  45
2   1   "Week"  10  20
2   2   "Month" 30  40
3   1   "Week"  5   10
3   2   "Month" 15  20

附言使用 t.* 查看展平后可用的内容(也许很明显。)

,

您也可以使用 UNPIVOTNATURAL JOIN

上面的答案很好......就像考虑其他的做事方式一样......你永远不知道它什么时候可能适合你的需求 - 并且让你接触到一些新的很酷的功能。

enter image description here

with cte as (
select
    1 PersonID,15 CW_MilesRun,25 PW_MilesRun,35 CM_MilesRun,45 PM_MilesRun
union
select
    2 PersonID,10 CW_MilesRun,20 PW_MilesRun,30 CM_MilesRun,40 PM_MilesRun
union
select
    3 PersonID,5 CW_MilesRun,10 PW_MilesRun,15 CM_MilesRun,20 PM_MilesRun
)
select * from
(select
   PersonID,CW_MilesRun weekly,CM_MilesRun monthly
 from
   cte
) unpivot (C_MilesRun for description in (weekly,monthly)) 
natural join 
(select * from
    (select
       PersonID,PW_MilesRun weekly,PM_MilesRun monthly
     from
       cte
    ) unpivot (P_MilesRun for description in (weekly,monthly))) f