我可以在Postgres中为WHERE条件创建别名吗?

时间:2017-08-03 21:41:14

标签: sql postgresql

我想找到所有符合某些标准的员工的公司,并返回有关这些员工的信息,以及这些公司的所有者。我的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别名的信息。

2 个答案:

答案 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;