簡體   English   中英

在 Snowflake 中,如何解析未命名的 JSON 數組並使用鍵值而不是數組切片方法訪問每個鍵?

[英]In Snowflake, how do I parse an unnamed JSON array and access each key with key value rather than array slicing methods?

我在雪花中有一個 JSON 數組,我需要在其中解析成一個表,即將所有信息轉換成一行。 假設我的表包含兩列:id 和 json_tag 列。

示例行如下:

{ [
json_tag

[
  {
    "key": "app.name",
    "value": "myapp1"
  },
  {
    "key": "device.name",
    "value": "myiPhone11"
  },
  {
    "key": "iOS.dist",
    "value": "latestDist5"
  }
]

這不是一個標准的例子,另一個例子可以有 5 個甚至 6 個新的鍵名。 下面是一個例子:

{ [
json_tag

[
  {
    "key": "app.name",
    "value": "myapp2"
  },
  {
    "key": "app.cost",
    "value": "$2.99"
  },
  {
    "key": "device.name",
    "value": "myiPhoneX"
  },
  {
    "key": "device.color",
    "value": "gold"
  },
  {
    "key": "iOS.dist",
    "value": "latestDist4.9"
  }
]

我想要的是處理一張表(不創建新表),其中 json 行被分成如下列:

id app.name app.cost device.name device.color iOS.dist 
1  myapp1   null     myiPhone11  null         latestDist5
2  myapp2   $2.99    myiPhoneX   gold         latestDist4.9

我嘗試了以下代碼段:

with parsed_tb as (
    select id, 
           to_variant(parse_json(json_tag)) as parsed_json_tag
    from mytable
)



 select parsed_json_tag[0]:value::varchar as app_name, 
        parsed_json_tag[1]:value::varchar as app_cost, 
        parsed_json_tag[2]:value::varchar as device_name
 from tb; 

可以想象,當鍵值中沒有 app.cost 或每一行的鍵和值的數量不同時,上面的代碼段不起作用。

我在雪花中嘗試了lateral flatten命令,但是創建了很多行,我無法弄清楚如何將它們放在同一行的列中。 我也嘗試使用recursive命令,但無法實現。

所以我的問題是:

  1. 如何按名稱訪問鍵,而不是像上面那樣對數組進行切片? - 我想這會解決我的問題。

  2. 如果我想的 #1 解決方案不能解決,我怎樣才能獲得上表?

在以下線程的幫助下,我找到了解決此問題的方法:

Mysql,從長/高到寬重塑數據

解決方案是首先使用唯一標識符解析 json 列,然后橫向展平,然后按唯一標識符對結果進行分組[格式表從長到寬,如上面的鏈接中給出的]。

因此,對於我上面提供的示例,解決方案如下:

with tb as (
     select id, 
            to_variant(parse_json(json_tags)) as parsed_json_tags
     from mytable
), 

flattened as (
     select id,
            VALUE:value::string as value, 
            VALUE:key::string as key
     from mytable, lateral flatten(input => (tb.parsed_json_tags))
)

select id, 
       MAX( IFF( key='app.name', value, NULL ) ) AS app_name,
       MAX( IFF( key='app.cost', value, NULL ) ) AS app_cost,
       MAX( IFF( key='device.name', value, NULL ) ) AS device_name,
       MAX( IFF( key='device.color', value, NULL ) ) AS device_color,
       MAX( IFF( key='iOS.dist', value, NULL ) ) AS ios_dist

from flattened
group by 1;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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