如果连接没有匹配,如何与json_build_object一起返回null?

时间:2015-12-25 02:32:52

标签: json postgresql

我有两张桌子,一张是另一张外键:

CREATE TABLE employee (
  employee_id INT PRIMARY KEY,
  name TEXT NOT NULL
);

CREATE TABLE project (
  project_id INT PRIMARY KEY,
  employee_id INT NOT NULL REFERENCES employee(employee_id),
  name text NOT NULL
);

我试图查询员工及其项目(假设只允许一个项目)。如果项目存在,我希望项目显示为JSON对象,否则我理想地喜欢null

我已经得到了以下查询,这就是我喜欢的...

SELECT e.employee_id,
       e.name,
       row_to_json(p.*) AS project
FROM employee e
LEFT JOIN project p USING(employee_id)

问题是,我想有选择地从联接中选择列,因此我将查询调整为如下:

SELECT e.employee_id,
       e.name,
       json_build_object('name', p.name) AS project
FROM employee e
LEFT JOIN project p USING(employee_id)

上述查询的问题在于,如果员工没有匹配的项目,json_build_object仍会生成一个具有空值的对象,而不是生成一个对象。 row_to_json查询能够看到连接没有匹配的行,因此它不会创建json对象。

有没有办法实现我正在寻找的东西,同时能够使用我选择的列构建自己的JSON对象?

1 个答案:

答案 0 :(得分:2)

您可以使用CASE检查值是否为空:

SELECT e.employee_id,
       e.name,
       CASE 
            WHEN p.name IS NULL THEN NULL
            ELSE json_build_object('name', p.name) 
       END AS project
FROM employee e
LEFT JOIN project p USING(employee_id);

如果您打算重复选择不同的值,此功能非常有用:

create or replace function to_json_or_null(key text, val text)
returns json language sql as $$
    select case
        when val is null then null
        else json_build_object(key, val)
    end
$$;

SELECT e.employee_id,
       e.name,
       to_json_or_null('name', p.name) AS project
FROM employee e
LEFT JOIN project p USING(employee_id);