我有两张桌子,一张是另一张外键:
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对象?
答案 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);