Tar*_*len 1 sql postgresql json jsonb
我有一张桌子
Visitor: (id, signup_up, sessions, email, custom_fields)
custom_fields表单的JSON对象的jsonb数组在哪里
CustomField: ( field, value ) 例: (domain, www.somedomain.com)
我想获取signed_up, sessions, email列和它们的值,以及数组中的CustomFieldjson对象custom_fields,并将它们合并到data使用相同CustomField结构调用的第3个字段中,即.每个条目都有表格field: value.
例
鉴于这些行
id | sessions | email              | custom_fields
---------------------------------------------------------------
1  | 3        | test@gmail.com      [{ field: domain, value: "www.hello.com" }, { field: type, value: "Customer" }]
---------------------------------------------------------------
2  | 5        | another@gmail.com   [{ field: domain, value: "www.other.com" }, { field: type, value: "Customer" }]
Run Code Online (Sandbox Code Playgroud)
我想得到
id | fields
-----------------------
1  | [{sessions: 3, email: test@gmail.com, domain: "www.hello.com", type: "Customer"}]
----------------------
2  | [{sessions: 5, email: another@gmail.com, domain: "www.other.com", type: "Customer"}]
Run Code Online (Sandbox Code Playgroud)
有关如何实现这一点的任何想法?
任何帮助深表感谢
示例数据(这应该是问题的一部分,而不是答案;请注意正确的json语法):
create table visitor (id int, sessions int, email text, custom_fields jsonb);
insert into visitor values
(1, 3, 'test@gmail.com', '[{"field": "domain", "value": "www.hello.com" }, {"field": "type", "value": "Customer"}]'),
(2, 5, 'another@gmail.com', '[{"field": "domain", "value": "www.other.com" }, {"field": "type", "value": "Customer"}]');
Run Code Online (Sandbox Code Playgroud)
提示1.使用jsonb_array_elements()和选择的JSON值field和value列key和value:
select id, sessions, email, elem->>'field' as key, elem->>'value' as value
from visitor, jsonb_array_elements(custom_fields) elem;
 id | sessions |       email       |  key   |     value     
----+----------+-------------------+--------+---------------
  1 |        3 | test@gmail.com    | domain | www.hello.com
  1 |        3 | test@gmail.com    | type   | Customer
  2 |        5 | another@gmail.com | domain | www.other.com
  2 |        5 | another@gmail.com | type   | Customer
(4 rows)
Run Code Online (Sandbox Code Playgroud)
提示2.用于jsonb_object_agg()将这些pair(key, value)聚合到json对象中:
select 
    id, 
    jsonb_object_agg(key, value)
from (
    select id, sessions, email, elem->>'field' as key, elem->>'value' as value
    from visitor, jsonb_array_elements(custom_fields) elem
    ) s
group by id, sessions, email
order by id;
 id |                jsonb_object_agg                 
----+-------------------------------------------------
  1 | {"type": "Customer", "domain": "www.hello.com"}
  2 | {"type": "Customer", "domain": "www.other.com"}
(2 rows)
Run Code Online (Sandbox Code Playgroud)
最终查询.从添加内置列(串连)JSON对象session和email,并建立与所有对象JSON数组:
select 
    id, 
    json_build_array(
        jsonb_object_agg(key, value) ||
        jsonb_build_object('sessions', sessions, 'email', email)
        ) as fields
from (
    select id, sessions, email, elem->>'field' as key, elem->>'value' as value
    from visitor, jsonb_array_elements(custom_fields) elem
    ) s
group by id, sessions, email
order by id;
 id |                                             fields                                             
----+------------------------------------------------------------------------------------------------
  1 | [{"type": "Customer", "email": "test@gmail.com", "domain": "www.hello.com", "sessions": 3}]
  2 | [{"type": "Customer", "email": "another@gmail.com", "domain": "www.other.com", "sessions": 5}]
(2 rows)
Run Code Online (Sandbox Code Playgroud)
还有一个提示(或技巧):
select '{"a": null}'::jsonb || '{"a": 1}'::jsonb;
 ?column? 
----------
 {"a": 1}
(1 row) 
Run Code Online (Sandbox Code Playgroud)
        |   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           963 次  |  
        
|   最近记录:  |