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

时间:2021-03-15 18:23:42

标签: sql json snowflake-cloud-data-platform variant

我在 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"
        }]
    }]
}

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:2)

通过使用函数 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

答案 1 :(得分:1)

您需要使用 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 stackoverflow;

use database stackoverflow;

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);