如何取消嵌套 JSON 数据对象并使用 Snowflake 创建简化的 JSON?

发布于 2025-01-20 17:29:32 字数 1125 浏览 0 评论 0 原文

我当前的 JSON 对象如下所示:

-- create a sample table
create or replace table json_example(v variant);
-- create sample json record
insert into json_example
select parse_json(
    '[
      {
        "key": "variable_a",
        "value": {
          "double_value": null,
          "float_value": null,
          "int_value": null,
          "string_value": "https://example.com"
        }
      },
      {
        "key": "variable_b",
        "value": {
          "double_value": null,
          "float_value": null,
          "int_value": 2,
          "string_value": null
        }
      }
     ]');

这是我想要实现的简化 JSON:

  {
    "variable_a": "https://example.com",
    "variable_b": 2
  }

How can I get the simple JSON from the multilevel JSON object?

我就是这样想的:

select value:key::string as key, value:value:string_value::varchar as value
from json_example, lateral flatten(input => v)
union all
select value:key::string as key, value:value:int_value::varchar as value
from json_example, lateral flatten(input => v)

先谢谢你了。

My current JSON object looks like this:

-- create a sample table
create or replace table json_example(v variant);
-- create sample json record
insert into json_example
select parse_json(
    '[
      {
        "key": "variable_a",
        "value": {
          "double_value": null,
          "float_value": null,
          "int_value": null,
          "string_value": "https://example.com"
        }
      },
      {
        "key": "variable_b",
        "value": {
          "double_value": null,
          "float_value": null,
          "int_value": 2,
          "string_value": null
        }
      }
     ]');

And this is the simplified JSON that I am trying to achieve:

  {
    "variable_a": "https://example.com",
    "variable_b": 2
  }

How can I get the simplified JSON from the multilevel JSON object?

This is how I started to think:

select value:key::string as key, value:value:string_value::varchar as value
from json_example, lateral flatten(input => v)
union all
select value:key::string as key, value:value:int_value::varchar as value
from json_example, lateral flatten(input => v)

Thank you in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

流云如水 2025-01-27 17:29:32

因此,如果您希望一切都成为json文本,则可以:

WITH data as (
select parse_json(
    '[
      {
        "key": "variable_a",
        "value": {
          "double_value": null,
          "float_value": null,
          "int_value": null,
          "string_value": "https://example.com"
        }
      },
      {
        "key": "variable_b",
        "value": {
          "double_value": null,
          "float_value": null,
          "int_value": 2,
          "string_value": null
        }
      }
     ]') as json
)
SELECT f.value:key::text as t_key
    ,try_to_double(f.value:value:double_value::text) as d_val
    ,try_to_double(f.value:value:float_value::text) as f_val
    ,try_to_number(f.value:value:int_value::text) as n_val
    ,f.value:value:string_value::text as s_val
    ,coalesce(d_val::text, f_val::text, n_val::text, s_val) as c_val
    ,object_construct(t_key, c_val) as obj
FROM DATA, lateral flatten(input=>json) f
t_key d_val f_val n_val s_val s_val c_val obj abj
variable_a https://example.com https://example.com
varibal_b 2 2,

然后向我们展示我们如何构建案例语句,以及如何构建案例语句,并且构建干净的本机对象,例如:

SELECT 
    case 
        when not is_null_value(f.value:value:double_value) 
            then object_construct(f.value:key::text, try_to_double(f.value:value:double_value::text))
        when not is_null_value(f.value:value:float_value) 
            then object_construct(f.value:key::text, try_to_double(f.value:value:float_value::text))
        when not is_null_value(f.value:value:int_value) 
            then object_construct(f.value:key::text, try_to_number(f.value:value:int_value::text))
        else 
            object_construct(f.value:key::text, f.value:value:string_value::text)
    end obj
FROM DATA, lateral flatten(input=>json) f
obj
{“ variable_a”:“ https://example.com”}
{“ variable_b”:2},

可以将其变成一个单个对象,例如so:

SELECT 
    object_agg(f.value:key, 
    case 
        when not is_null_value(f.value:value:double_value) 
            then try_to_double(f.value:value:double_value::text)
        when not is_null_value(f.value:value:float_value) 
            then try_to_double(f.value:value:float_value::text)
        when not is_null_value(f.value:value:int_value) 
            then try_to_number(f.value:value:int_value::text)
        else 
            f.value:value:string_value
    end
   ) as obj
FROM DATA, lateral flatten(input=>json) f
obj
{“ variable_a”:“ https:/https:/https:/ /example.com”,“ variable_b”:2}

So if you want everthing thing to be JSON text you can:

WITH data as (
select parse_json(
    '[
      {
        "key": "variable_a",
        "value": {
          "double_value": null,
          "float_value": null,
          "int_value": null,
          "string_value": "https://example.com"
        }
      },
      {
        "key": "variable_b",
        "value": {
          "double_value": null,
          "float_value": null,
          "int_value": 2,
          "string_value": null
        }
      }
     ]') as json
)
SELECT f.value:key::text as t_key
    ,try_to_double(f.value:value:double_value::text) as d_val
    ,try_to_double(f.value:value:float_value::text) as f_val
    ,try_to_number(f.value:value:int_value::text) as n_val
    ,f.value:value:string_value::text as s_val
    ,coalesce(d_val::text, f_val::text, n_val::text, s_val) as c_val
    ,object_construct(t_key, c_val) as obj
FROM DATA, lateral flatten(input=>json) f
T_KEY D_VAL F_VAL N_VAL S_VAL C_VAL OBJ
variable_a https://example.com https://example.com
variable_b 2 2

Which then shows us how to build a CASE statement, and build clean native objects like:

SELECT 
    case 
        when not is_null_value(f.value:value:double_value) 
            then object_construct(f.value:key::text, try_to_double(f.value:value:double_value::text))
        when not is_null_value(f.value:value:float_value) 
            then object_construct(f.value:key::text, try_to_double(f.value:value:float_value::text))
        when not is_null_value(f.value:value:int_value) 
            then object_construct(f.value:key::text, try_to_number(f.value:value:int_value::text))
        else 
            object_construct(f.value:key::text, f.value:value:string_value::text)
    end obj
FROM DATA, lateral flatten(input=>json) f
OBJ
{ "variable_a": "https://example.com" }
{ "variable_b": 2 }

Which can be turned into a single object like so:

SELECT 
    object_agg(f.value:key, 
    case 
        when not is_null_value(f.value:value:double_value) 
            then try_to_double(f.value:value:double_value::text)
        when not is_null_value(f.value:value:float_value) 
            then try_to_double(f.value:value:float_value::text)
        when not is_null_value(f.value:value:int_value) 
            then try_to_number(f.value:value:int_value::text)
        else 
            f.value:value:string_value
    end
   ) as obj
FROM DATA, lateral flatten(input=>json) f
OBJ
{ "variable_a": "https://example.com", "variable_b": 2 }
橘寄 2025-01-27 17:29:32

这有三个部分:

  1. 将原始的JSON数组弄平,然后从中选择所需的值
  2. 创建新的JSON对象,以结果的行值。
  3. 将JSON对象组合到一个对象中。
with json_example(json) as (
  select parse_json(
      '[
        {
          "key": "variable_a",
          "value": {
            "double_value": null,
            "float_value": null,
            "int_value": null,
            "string_value": "https://example.com"
          }
        },
        {
          "key": "variable_b",
          "value": {
            "double_value": null,
            "float_value": null,
            "int_value": 2,
            "string_value": null
          }
        }
       ]'
  )
),
flattened_rows as
(
      select v.value:key::string as key, 
        v.value:value:int_value::int as int_value,
        v.value:value:string_value::string as string_value
        -- other values here
    from json_example, lateral flatten(input => json) as v
)
,
simplified_json as 
(
  select
    case when int_value is not null then object_construct(key, int_value)::variant
    else object_construct(key, string_value)
    end as json
  from flattened_rows
)
select object_agg(j.key, j.value)
from simplified_json, lateral flatten(input => json) AS j
;

flattened_rows 看起来像这样:

int_value string_value
variable_a https://example.com
variable_b 2

这样:

simpleified_json
看起来像 com“}
{“ variable_b”:2}

最终结果:

obj
{{“ variable_a”:“ https://example.com”,“ variable_b”:2}

更新

我更新了上面的答案以将上面的答案合并到 object_agg 找到Simeon的方法。我的原始答案涉及创建利用 object.assign 组合JSON对象的JavaScript UDTF。

There are three parts to this:

  1. flatten the original JSON array and select the values you want from it
  2. create new JSON objects based on the resulting row values.
  3. combine the JSON objects into a single object.
with json_example(json) as (
  select parse_json(
      '[
        {
          "key": "variable_a",
          "value": {
            "double_value": null,
            "float_value": null,
            "int_value": null,
            "string_value": "https://example.com"
          }
        },
        {
          "key": "variable_b",
          "value": {
            "double_value": null,
            "float_value": null,
            "int_value": 2,
            "string_value": null
          }
        }
       ]'
  )
),
flattened_rows as
(
      select v.value:key::string as key, 
        v.value:value:int_value::int as int_value,
        v.value:value:string_value::string as string_value
        -- other values here
    from json_example, lateral flatten(input => json) as v
)
,
simplified_json as 
(
  select
    case when int_value is not null then object_construct(key, int_value)::variant
    else object_construct(key, string_value)
    end as json
  from flattened_rows
)
select object_agg(j.key, j.value)
from simplified_json, lateral flatten(input => json) AS j
;

flattened_rows looks like this:

KEY INT_VALUE STRING_VALUE
variable_a https://example.com
variable_b 2

simplified_json looks like this:

JSON
{ "variable_a": "https://example.com" }
{ "variable_b": 2 }

Final results:

OBJ
{ { "variable_a": "https://example.com", "variable_b": 2 }

Update

I updated the answer above to incorporate the object_agg approach Simeon found. My original answer involved creating a JavaScript UDTF that leveraged Object.assign to combine the json objects.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文