簡體   English   中英

使用 Snowflake SQL 將字符串解析為 JSON

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM