我想找到所有符合某些标准的员工的公司,并返回有关这些员工的信息,以及这些公司的所有者。我的SQL有点重复,我想知道是否有办法在我的某些WHERE条件中使用别名。
考虑这个问题:
SELECT json_agg(employee.*) employees_and_admins, company.*
FROM company
JOIN employee ON employee.company_id = company.id
WHERE employee.owner IS TRUE
-- This is where the repetitive stuff starts
OR employee.first_name IS NULL
OR employee.last_name IS NULL
OR employee.date_of_birth IS NULL
OR employee.hire_date IS NULL
OR employee.email IS NULL
GROUP BY company.id
HAVING sum(CASE
-- Note the repetition; note also we're not checking employee.owner here
WHEN (
employee.first_name IS NULL
OR employee.last_name IS NULL
OR employee.date_of_birth IS NULL
OR employee.hire_date IS NULL
OR employee.email IS NULL)
THEN 1 ELSE 0 END) > 0;
有没有办法避免重复所有这些OR条件?在线搜索答案有点听说,因为我一直在获取有关SELECT别名的信息。
答案 0 :(得分:2)
lateral
和方便的bool_or
:
select json_agg(employee.*) employees_and_admins, company.*
from
company
inner join
employee on employee.company_id = company.id
cross join lateral (
select
employee.first_name is null
or employee.last_name is null
or employee.date_of_birth is null
or employee.hire_date is null
or employee.email is null
as any_null
) cjl
where employee.owner or any_null
group by company.id
having bool_or(any_null)
横向的替代方法是嵌套查询。
答案 1 :(得分:1)
您可以创建一个更好的可读性功能(这实际上不会影响性能),例如
CREATE OR REPLACE FUNCTION has_a_null_value(e employee)
RETURNS boolean LANGUAGE SQL AS $$
SELECT
e.first_name IS NULL
OR e.last_name IS NULL
OR e.date_of_birth IS NULL
OR e.hire_date IS NULL
OR e.email IS NULL
$$;
SELECT json_agg(employee.*) employees_and_admins, company.*
FROM company
JOIN employee ON employee.company_id = company.id
WHERE employee.owner OR has_a_null_value(employee)
GROUP BY company.id
HAVING sum(has_a_null_value(employee)::int) > 0;