查询雪花中的半结构化字段

Posted

技术标签:

【中文标题】查询雪花中的半结构化字段【英文标题】:Querying Semi-structured Field In Snowflake 【发布时间】:2021-03-15 18:23:42 【问题描述】:

我在 Snowflake 中有一个表,其中有一个类型为 varchar 的字段,但其中的数据结构为 json(不理想,我知道)。鉴于此字段中的以下示例数据,我如何在此字段的查询中返回“id”值和“tax_lines.price_set.amount”值?

例如


    "self": [
        "id": "abcdefg",
        "location": 
            "address1": "11234 street name"
        ,
        "tax_lines": [
            "price": 1.04,
            "price_set": 
                "presentment_money": 
                    "amount": "1.04",
                    "currency_code": "USD"
                ,
                "shop_money": 
                    "amount": "1.04",
                    "currency_code": "USD"
                
            ,
            "rate": 0.0575,
            "title": "xx STATE TAX"
        , 
            "price": 0.18,
            "price_set": 
                "presentment_money": 
                    "amount": "0.18",
                    "currency_code": "USD"
                ,
                "shop_money": 
                    "amount": "0.18",
                    "currency_code": "USD"
                
            ,
            "rate": 0.01,
            "title": "XX COUNTY TAX"
        ]
    ]

非常感谢任何帮助!

【问题讨论】:

路径tax_lines.price_set.amount 不存在也无济于事。首先,您有一个包含两条税线的数组,因此您可能希望每条税线有一行,或者两个元素都在同一行中?这还不清楚。然后每个元素都包含两个以数量结尾的不同路径,所以也许你想要两者?请使用您需要的确切要求和确切结果更新您的问题。 @MatBailie 是的,每条税行一行,每行两个金额。 【参考方案1】:

通过使用函数JSON_EXTRACT_PATH_TEXT

select *
, JSON_EXTRACT_PATH_TEXT(jsonColumn, 'self[0].id') id
, JSON_EXTRACT_PATH_TEXT(jsonColumn, 'self[0].tax_lines[0].price_set.presentment_money.amount') amount1
from table

【讨论】:

谢谢你,我认为这让我更接近,但我得到了所有的空值返回。我确定它与引用或其他东西有关,但不确定。我尝试了您提供的内容以及以下内容,然后在字段周围加上双引号。不知道还能做什么...从 XYZtable 中选择 JSON_EXTRACT_PATH_TEXT(Line_Items, '"tax_lines"."price_set"."amount"') 金额 不幸的是,它仍然返回所有空值。很奇怪! 文件说:The function returns NULL if the path name does not correspond to any element.,所以请确保路径正确 它仍然返回每个值的空值。我的数据的结构与我在原始帖子中的结构完全一样,看起来这会起作用,但也许该字段中的语法需要更新? 实际上,如果你检查你的 json ,它不是一个 vlid json ,缺少 cloding 在 and 和 "location"" 之后有一个额外的双引号,所以我想如果你修复你的 json 结构有效【参考方案2】:

您需要使用 VARIANT 数据类型和 LATERAL FLATTEN 在 Snowflake 中处理此类数据。

select var:self[0]:id::string
  , value:price_set:presentment_money:amount::float
  , value:price_set:shop_money:amount::float
from json_table
  , lateral flatten(input => var:self[0]:tax_lines);

会给你以下结果:

ID         PRESENTMENT_AMOUNT SHOP_MONEY_AMOUNT
abcdefg    1.04               1.04
abcdefg    0.18               0.18

这是完整的工作簿:

create database ***;

use database ***;

create or replace table json_table (var variant);

insert into json_table (var)
  select  parse_json('
    "self": [
        "id": "abcdefg",
        "location": 
            "address1": "11234 street name"
        ,
        "tax_lines": [
            "price": 1.04,
            "price_set": 
                "presentment_money": 
                    "amount": "1.04",
                    "currency_code": "USD"
                ,
                "shop_money": 
                    "amount": "1.04",
                    "currency_code": "USD"
                
            ,
            "rate": 0.0575,
            "title": "xx STATE TAX"
        , 
            "price": 0.18,
            "price_set": 
                "presentment_money": 
                    "amount": "0.18",
                    "currency_code": "USD"
                ,
                "shop_money": 
                    "amount": "0.18",
                    "currency_code": "USD"
                
            ,
            "rate": 0.01,
            "title": "XX COUNTY TAX"
        ]
    ]
');

select var:self[0]:id::string
, value:price_set:presentment_money:amount::float
, value:price_set:shop_money:amount::float
from json_table
, lateral flatten(input => var:self[0]:tax_lines);

【讨论】:

以上是关于查询雪花中的半结构化字段的主要内容,如果未能解决你的问题,请参考以下文章

雪花 - 查询变体中的空值

变体列中唯一元素的雪花查询性能

雪花 XML 解析返回 NULL - 字段名称中的空格?

从 Databricks 加载雪花会更改表结构

python学习笔记——爬虫中提取网页中的信息

当 unpivot 未检测到具有不同类型的字段时,雪花如何转换选择查询的所有字段?