[英]Parse string as JSON with Snowflake SQL
我在我们的数据库表中有一个字段,它的工作方式类似于类似事件的有效负载,其中收集了对不同实体的所有更改。 请参阅下面的示例,了解 object 的单个字段:
'---\nfield_one: 1\nfield_two: 20\nfield_three: 4\nid: 1234\nanother_id: 5678\nsome_text: Hey you\na_date: 2022-11-29\nutc: this_utc\nanother_date: 2022-11-30\nutc: another_utc'
由于使用纯 SQL 访问此字段很痛苦,我正在考虑将其解析为 JSON 以便它看起来像这样:
{
"field_one":"1",
"field_two": "20",
"field_three": "4",
"id": "1234",
"another_id": "5678",
"some_text": "Hey you",
"a_date": "2022-11-29",
"utc": "2022-11-29 15:29:28.159296000 Z",
"another_date": "2022-11-30",
"utc": "2022-11-30 13:34:59.000000000 Z"
}
然后只需使用 Snowflake 原生方法来访问我需要的值。
不过,如您所见,有两个字段称为utc
,因为一个字段指的是第一个日期 ( a_date
),第二个字段指的是第二个日期 ( another_date)
。 我相信这些嵌套在 object 中,但很难用字段的格式进行评估。
这是一个问题,因为在为字符串提供我需要的格式并运行parse_json()
function(由于两个键使用相同的名称)时,我无法区分一个utc
和另一个。
到目前为止,我的 SQL 如下所示:
select
object,
replace(object, '---\n', '{"') || '"}' as first,
replace(first, '\n', '","') as second_,
replace(second_, ': ', '":"') as third,
replace(third, ' ', '') as fourth,
replace(fourth, ' ', '') as last
from my_table
(需要第三步和第四步,因为我有一些字段中有额外的空格)
这实际上给了我需要的格式,但由于我在utc
键周围提到的内容,我无法将字符串解析为 JSON。
另请注意,字符串的结构可能会因行而异,这意味着某些行可能收集两个utc
键,而其他行可能有一个,而其他行甚至有五个。
关于如何克服它的任何想法?
只用regexp_replace()
替换一次:
with data as (
select '---\nfield_one: 1\nfield_two: 20\nfield_three: 4\nid: 1234\nanother_id: 5678\nsome_text: Hey you\na_date: 2022-11-29\nutc: this_utc\nanother_date: 2022-11-30\nutc: another_utc' o
)
select parse_json(last2)
from (
select o,
replace(o, '---\n', '{"') || '"}' as first,
replace(first, '\n', '","') as second_,
replace(second_, ': ', '":"') as third,
replace(third, ' ', '') as fourth,
replace(fourth, ' ', '') as last,
regexp_replace(last, '"utc"', '"utc2"', 1, 2) last2
from data
)
;
这可能不是你想要的,但在我看来,如果 UTC 时间戳替换它之前的密钥不重复的日期,你的问题就可以解决。 一旦有了时间戳,您就可以随时计算日期。 如果这是有道理的,看看你是否可以将你的parse_json
解决方案应用于这个 output
set str='---\nfield_one: 1\nfield_two: 20\nfield_three: 4\nid: 1234\nanother_id: 5678\nsome_text: Hey you\na_date: 2022-11-29\nutc: 2022-11-29 15:29:28.159296000 Z\nanother_date: 2022-11-30\nutc: 2022-11-30 13:34:59.000000000 Z';
select regexp_replace($str,'[0-9]{4}-[0-9]{2}-[0-9]{2}\nutc:')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.