我在表中有一个列,其中包含与公司更改相关的任何更新的数据,格式如下 -
#=============#==============#================#
| Company ID | updated_at | updates |
#=============#==============#================#
| 101 | 2020-11-01 | name: |
| | | -ABC |
| | | -XYZ |
| | | url: |
| | | -www.abc.com |
| | | -www.xyz.com |
+-------------+--------------+----------------+
| 109 | 2020-10-20 | rating: |
| | | -4.5 |
| | | -4.0 |
+-------------+--------------+----------------+
正如您在上面所看到的,
updates
列包含包含换行符并描述一个或多个更新的字符串。在上面的示例中,这意味着对于 ID 101 的公司,名称从 ABC 更改为 XYZ,并且 url 从 www.abc.com 更改为 www.xyz.com。对于公司 ID 109,仅评级从 4.5 更改为 4.0。
但是我想将更新列分为 3 列 - 第一列应包含更改的内容(网址、名称等),第二列应包含旧值,第三列应包含新值。像这样的东西-
#============#============#==============#================#
| Company ID | Field | Old Value | New Value |
#============#============#==============#================#
| 101 | name | ABC | XYZ |
+------------+------------+--------------+----------------+
| 101 | url | www.abc.com | www.xyz.com |
+------------+------------+--------------+----------------+
| 109 | rating | 4.5 | 4.0 |
+------------+------------+--------------+----------------+
我正在雪花中这样做。我知道如何在 postgres 中执行此操作(使用正则表达式拆分到表和 split_part 函数),但雪花不支持正则表达式拆分到表,因此我有点卡住了。任何帮助,将不胜感激。谢谢!
我尝试使用常规(不是正则表达式) split_to_table 函数来执行此操作,但显然结果不正确。我还尝试使用 object_construct 将文本转换为键值对,但将该文本转换为键值对也很困难
我认为 split() 或 split_to_table() 实际上是正确的方法,您只需要在事后进行一些操作即可。此查询并不能完全满足您的需求,因为我为案例陈述添加了一个额外的列,并且不包括原始记录,但这基于您提供的数据:
第一部分只是将
updates
字段复制到列中:
with x as (
select 'name:
-ABC
-XYZ
url:
-www.abc.com
-www.xyz.com'::string as str
)
使用下面横向展平中的分割,我可以使用 Lead() 函数来获取接下来的 2 条记录(旧值和新值)。这假设您的格式在每个记录中都是一致的,但确实按照您上面描述的那样工作:
select trim(y.value::string,'-,:') as field,
case when right(value,1) = ':' then 'name' else 'value' end as field_type,
case when field_type = 'name' then
lead(field,1) over (partition by seq order by index)
end as old_value,
case when field_type = 'name' then
lead(field,2) over (partition by seq order by index)
end as new_value
from x,
lateral flatten(input=>split(str,'\n')) y
qualify field_type = 'name';