将JSON数组转换为PostgreSQL数组以在联接中使用

时间:2018-11-27 15:17:11

标签: arrays json postgresql join

我正在使用Postgres 9.6,并且有以下两个表:

CASE

现在,我想获得如下输出:

create table employees (
  id text,
  setting_id text -- references settings.id
);

create table settings (
  id text,
  setting_str text -- contains json string
);

insert into employees (id, setting_id) values ('e1', 's1');
insert into employees (id, setting_id) values ('e2', 's2');

insert into settings (id, setting_str)
   values ('s1', '{"vehicles" : null}');
insert into settings (id, setting_str)
   values ('s2', '{"vehicles" : ["Car", "Bike"]}');

我尝试了以下查询:

employee_id, name, vehicles
e1, one, null
e2, two, {"Car", "Bike"}

但这给我一个错误:

select e.id,
       jsonb_array_elements_text(s.setting_str::jsonb #> '{vehicles}')
from employees e
   join settings s on s.id = e.setting_id;

您知道如何从文本字段中提取JSON数组并将其显示为select语句中的Postgres字符串数组(不是ERROR: cannot extract elements from a scalar 数组,不是json)吗?

1 个答案:

答案 0 :(得分:0)

数据模型不好,因此查询会很复杂。

对于这样的数据,您应该使用关系模型。

以下是带有嵌入式注释的查询:

SELECT e.id AS employee_id,
       s.id AS setting_id,
       /* construct an array of all vehicles that are not NULL */
       array_agg(v.p) FILTER (WHERE v.p IS NOT NULL) AS vehicles
FROM employees AS e
   JOIN settings AS s ON e.setting_id = s.id
   /* join with the "exploded" JSON array from s.setting_str */
   LEFT JOIN LATERAL json_array_elements_text(
                        /* replace "null" with an empty array */
                        COALESCE(
                           (s.setting_str::json) ->> 'vehicles',
                           '[]'
                        )::json
                     ) AS v(p) ON TRUE
GROUP BY e.id, s.id;

 employee_id | setting_id |  vehicles  
-------------+------------+------------
 e1          | s1         | 
 e2          | s2         | {Car,Bike}
(2 rows)