在 Snowflake 中从 Table 中取消嵌套
Unnest from Table in Snowflake
我有以下 table:
PersonID CW_MilesRun PW_MilesRun CM_MilesRun PM_MilesRun
1 15 25 35 45
2 10 20 30 40
3 5 10 15 20
...
我需要将这个 table 拆分成一个垂直的 table,每个字段都有一个 id(即 CD_MilesRun =1,CW_MilesRun = 2,等等)所以我的 table 看起来类似于:
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
;
但是,我无法在 snowflake 中使用类似的功能。有什么想法吗?
您可以使用 FLATTEN()
和 LATERAL
来获得您想要的结果,尽管查询完全不同。
with tbl as (select PersonID, CW_MilesRun, PW_MilesRun, CM_MilesRun, PM_MilesRun from values (1, 15, 25, 35, 45),(2, 10, 20, 30, 40),(3, 5, 10, 15, 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
P.S。使用 t.*
查看展平后可用的内容(也许这是显而易见的。)
您也可以使用 UNPIVOT and NATURAL JOIN。
上面的答案很好......就像思考其他做事方式一样......你永远不知道什么时候它可能适合你的需要 - 并且让你接触到几个很酷的新功能。
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
我有以下 table:
PersonID CW_MilesRun PW_MilesRun CM_MilesRun PM_MilesRun
1 15 25 35 45
2 10 20 30 40
3 5 10 15 20
...
我需要将这个 table 拆分成一个垂直的 table,每个字段都有一个 id(即 CD_MilesRun =1,CW_MilesRun = 2,等等)所以我的 table 看起来类似于:
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
;
但是,我无法在 snowflake 中使用类似的功能。有什么想法吗?
您可以使用 FLATTEN()
和 LATERAL
来获得您想要的结果,尽管查询完全不同。
with tbl as (select PersonID, CW_MilesRun, PW_MilesRun, CM_MilesRun, PM_MilesRun from values (1, 15, 25, 35, 45),(2, 10, 20, 30, 40),(3, 5, 10, 15, 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
P.S。使用 t.*
查看展平后可用的内容(也许这是显而易见的。)
您也可以使用 UNPIVOT and NATURAL JOIN。
上面的答案很好......就像思考其他做事方式一样......你永远不知道什么时候它可能适合你的需要 - 并且让你接触到几个很酷的新功能。
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