【问题标题】:How can I combine two tables to get json array in postgresql?如何组合两个表以在 postgresql 中获取 json 数组?
【发布时间】:2020-04-25 08:14:58
【问题描述】:

我在 postgresql 中有两个表

表 A

id | name | b_codes
---|------|---------
1  | abc  | a,b
2  | def  | null

表 B

code | name
-----|------
a    | xx
b    | yy

我怎样才能得到这些(重点是json数组):

查询 A.id=1:

{id: 1, name:'abc', b_codes:[{code: 'a', name: 'xx'}, {code: 'b', name: 'yy'}]}

查询 A.id=2:

{id: 2, name:'def', b_codes:[]}

或全部:

 id | name | codes
 ---|------|----------------------------------------------------
 1  | abc  | [{code: 'a', name: 'xx'}, {code: 'b', name: 'yy'}]
 2  | def  | []

【问题讨论】:

    标签: sql arrays json postgresql


    【解决方案1】:

    您首先需要规范化数据模型才能正确加入代码列表:

    select a.id, a.name, x.*
    from table_a a
      left join lateral (
        select b.code, b.name
        from unnest(string_to_array(a.b_codes, ',')) as c(code)
           join table_b b on b.code = c.code
      ) as x on true
    ; 
    

    这将返回以下结果:

    id | name | code | name
    ---+------+------+-----
     1 | abc  | a    | xx  
     1 | abc  | b    | yy  
     2 | def  |      |     
    

    代码可以直接聚合到派生表中(子查询):

    select a.id, a.name, coalesce(x.codes, '[]') as codes
    from table_a a
      left join lateral (
        select jsonb_agg(jsonb_build_object('code', b.code, 'name', b.name)) as codes
        from unnest(string_to_array(a.b_codes, ',')) as c(code)
           join table_b b on b.code = c.code
      ) as x on true
    ;  
    

    coalesce() 是获取 id = 2 的空数组所必需的,否则派生表中的列 codes 将为空。

    现在可以将其转换为 JSON 值:

    select jsonb_build_object('id', a.id, 'name', a.name, 'b_codes', coalesce(x.codes, '[]'))
    from table_a a
      left join lateral (
        select jsonb_agg(jsonb_build_object('code', b.code, 'name', b.name)) as codes
        from unnest(string_to_array(a.b_codes, ',')) as c(code)
           join table_b b on b.code = c.code
      ) as x on true
    ;  
    

    Online example

    【讨论】:

    • 非常感谢您的回复!那很完美!但是如果每张表有1万条记录,查询效率如何? (我是新人,所以我真的知道什么。)再次感谢~
    猜你喜欢
    • 1970-01-01
    • 2011-01-01
    • 2018-07-04
    • 2019-02-01
    • 1970-01-01
    • 2016-08-26
    • 2021-04-29
    • 2023-01-09
    • 2019-03-19
    相关资源
    最近更新 更多