如何将以分号分隔的列名和值字符串转换为新的 table
How to transform semicolon separated strings of column names and values into a new table
我对 Snowflake 比较陌生,在为半结构化数据集设置转换方面遇到了一些困难。我有几个日志数据批次,其中每个批次(Snowflake 中的 table 行)都有以下列:LOG_ID、COLUMN_NAMES 和 LOG_ENTRIES。
COLUMN_NAMES 包含以分号分隔的列名列表,例如:
“TIMESTAMP;Sensor A;Sensor B”, “TIMESTAMP;Sensor B;Sensor C”
LOG_ENTRIES:条目包含以分号分隔的值列表,例如
“2020-02-11 09:08:19; 99.24;12.25”
日志批次(雪花行)之间的 COLUMN_NAMES 字符串可能不同,但按它们出现顺序排列的名称描述同一行的 LOG_ENTRIES 列值的内容。我的目标是将数据转换为 table,其中包含 COLUMN_NAMES 列中存在的所有唯一值的列名,例如:
LOG_ID
TIMESTAMP
Sensor A
Sensor B
Sensor C
1
2020-02-11 09:08:19
99.24
12.25
NaN
2
2020-02-11 09:10:44
NaN
13.32
0.947
这可以用雪花脚本实现吗?如果可以,怎么做? :)
此致,
约翰
你应该使用SPLIT_TO_TABLE函数,拆分两个值,并通过索引连接它们。
之后,您所要做的就是使用 PIVOT 反转 table.
示例数据:
create or replace table splittable (LOG_ID int, COLUMN_NAMES varchar, LOG_ENTRIES varchar);
insert into splittable (LOG_ID, COLUMN_NAMES, LOG_ENTRIES)
values (1, 'TIMESTAMP;Sensor A;Sensor B', '2020-02-11 09:08:19;99.24;12.25'),
(2, 'TIMESTAMP;Sensor B;Sensor C', '2020-02-11 09:10:44;13.32;0.947');
解决方案建议:
WITH src AS (
select LOG_ID, cn.VALUE as COLUMN_NAMES, le.VALUE as LOG_ENTRIES
from splittable as st,
lateral split_to_table(st.COLUMN_NAMES, ';') as cn,
lateral split_to_table(st.LOG_ENTRIES, ';') as le
where cn.INDEX = le.INDEX
)
select * from src
pivot (min(LOG_ENTRIES) for COLUMN_NAMES in ('TIMESTAMP','Sensor A','Sensor B','Sensor C'))
order by LOG_ID;
参考:SPLIT_TO_TABLE, PIVOT
如果列列表是可变的并且您无法定义它,那么您必须编写一些生成器,也许它会有所帮助:CREATE A DYNAMIC PIVOT IN SNOWFLAKE
您可以将数据转换为 ACTUAL 半结构化数据类型,然后您可以使用 Snowflake 本机查询 SQL。
WITH x AS (
SELECT column_names, log_entries
FROM (VALUES ('TIMESTAMP_;SENSOR1','2021-02-01'||';1.2')) x (column_names, log_entries)
),
y AS (
SELECT *
FROM x,
LATERAL FLATTEN(input => split(column_names,';')) f
),
z AS (
SELECT *
FROM x,
LATERAL FLATTEN(input => split(log_entries,';')) f
)
SELECT listagg(('"'||y.value||'":"'||z.value||'"'),',') as cnt
, parse_json('{'||cnt||'}') as var
FROM y
JOIN z
ON y.seq = z.seq
AND y.index = z.index
GROUP BY y.seq;
我对 Snowflake 比较陌生,在为半结构化数据集设置转换方面遇到了一些困难。我有几个日志数据批次,其中每个批次(Snowflake 中的 table 行)都有以下列:LOG_ID、COLUMN_NAMES 和 LOG_ENTRIES。
COLUMN_NAMES 包含以分号分隔的列名列表,例如:
“TIMESTAMP;Sensor A;Sensor B”, “TIMESTAMP;Sensor B;Sensor C”
LOG_ENTRIES:条目包含以分号分隔的值列表,例如
“2020-02-11 09:08:19; 99.24;12.25”
日志批次(雪花行)之间的 COLUMN_NAMES 字符串可能不同,但按它们出现顺序排列的名称描述同一行的 LOG_ENTRIES 列值的内容。我的目标是将数据转换为 table,其中包含 COLUMN_NAMES 列中存在的所有唯一值的列名,例如:
LOG_ID | TIMESTAMP | Sensor A | Sensor B | Sensor C |
---|---|---|---|---|
1 | 2020-02-11 09:08:19 | 99.24 | 12.25 | NaN |
2 | 2020-02-11 09:10:44 | NaN | 13.32 | 0.947 |
这可以用雪花脚本实现吗?如果可以,怎么做? :)
此致, 约翰
你应该使用SPLIT_TO_TABLE函数,拆分两个值,并通过索引连接它们。 之后,您所要做的就是使用 PIVOT 反转 table.
示例数据:
create or replace table splittable (LOG_ID int, COLUMN_NAMES varchar, LOG_ENTRIES varchar);
insert into splittable (LOG_ID, COLUMN_NAMES, LOG_ENTRIES)
values (1, 'TIMESTAMP;Sensor A;Sensor B', '2020-02-11 09:08:19;99.24;12.25'),
(2, 'TIMESTAMP;Sensor B;Sensor C', '2020-02-11 09:10:44;13.32;0.947');
解决方案建议:
WITH src AS (
select LOG_ID, cn.VALUE as COLUMN_NAMES, le.VALUE as LOG_ENTRIES
from splittable as st,
lateral split_to_table(st.COLUMN_NAMES, ';') as cn,
lateral split_to_table(st.LOG_ENTRIES, ';') as le
where cn.INDEX = le.INDEX
)
select * from src
pivot (min(LOG_ENTRIES) for COLUMN_NAMES in ('TIMESTAMP','Sensor A','Sensor B','Sensor C'))
order by LOG_ID;
参考:SPLIT_TO_TABLE, PIVOT
如果列列表是可变的并且您无法定义它,那么您必须编写一些生成器,也许它会有所帮助:CREATE A DYNAMIC PIVOT IN SNOWFLAKE
您可以将数据转换为 ACTUAL 半结构化数据类型,然后您可以使用 Snowflake 本机查询 SQL。
WITH x AS (
SELECT column_names, log_entries
FROM (VALUES ('TIMESTAMP_;SENSOR1','2021-02-01'||';1.2')) x (column_names, log_entries)
),
y AS (
SELECT *
FROM x,
LATERAL FLATTEN(input => split(column_names,';')) f
),
z AS (
SELECT *
FROM x,
LATERAL FLATTEN(input => split(log_entries,';')) f
)
SELECT listagg(('"'||y.value||'":"'||z.value||'"'),',') as cnt
, parse_json('{'||cnt||'}') as var
FROM y
JOIN z
ON y.seq = z.seq
AND y.index = z.index
GROUP BY y.seq;