【问题标题】:Generate a JSON array of values for each row为每一行生成一个 JSON 值数组
【发布时间】:2021-07-22 02:32:22
【问题描述】:

假设以下 CTE:

with mytable as (
    select column1 as foo, column2 as bar, column3 as baz
    from (values
      ('a', 'b', 1),
      ('c', 'd', 2)
    ) v
)

使用array_agg() 输出一个值数组:

select
    array_agg(v)
from mytable v;

-- {"(a,b,1)","(c,d,2)"}

但令人惊讶的是(至少对我而言),在此数组上使用 to_json() 会将字段名称恢复为每一行的对象

select
    to_json(array_agg(v))
from mytable v;

-- [{"foo":"a","bar":"b","baz":1},{"foo":"c","bar":"d","baz":2}]

我们如何让 PostgreSQL 输出一个数组而不是数组,将每一行呈现为一个值数组?

select
    something(v)
from mytable v;

-- [["a", "b", 1],["c", "d", 2]]

【问题讨论】:

    标签: sql arrays json postgresql postgresql-13


    【解决方案1】:

    您可以将一行转换为 json,然后取消嵌套键/值对,然后将值聚合回来:

    with mytable (foo, bar, baz) as (
      values
        ('a', 'b', 1),
        ('c', 'd', 2)
    )
    select jsonb_agg(x.vals)
    from mytable m
      cross join lateral (
        select jsonb_agg(value order by idx) as vals
        from json_each(row_to_json(m)) with ordinality as t(key,value,idx)
      ) x
    

    如果数组中列值的顺序对您很重要,请务必使用json 转换行。

    如果你经常需要这个,你可以把它放到一个函数中。


    如果数组中列值的顺序不重要,可以使用 JSON 路径函数:

    select jsonb_path_query_array(to_jsonb(m), '$.keyvalue().value')
    from mytable m;
    

    【讨论】:

      【解决方案2】:

      除了 a_horse_with_no_name 的答案之外,我刚刚找到了一种方法来实现这一点,假设列名是已知的:

      with mytable as (
          select column1 as foo, column2 as bar, column3 as baz
          from (values
            ('a', 'b', 1),
            ('c', 'd', 2)
          ) v
      )
      
      select
          to_json(array_agg(x.vals))
      from (
          select
              json_build_array(
                  v.foo,
                  v.bar,
                  v.baz
              ) as vals
          from mytable v
      ) x
      ;
      
      -- [["a", "b", 1],["c", "d", 2]]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-10-10
        • 2020-09-10
        • 2018-09-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多