2017-08-03 63 views
1

我想找到所有符合特定標準的員工的公司,並返回有關這些員工的信息,以及這些公司的所有者。不過,我的SQL有點重複,我想知道是否有一種方法可以爲我的某些WHERE條件使用別名。我可以在Postgres中爲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

簡短的回答,沒有。長答案。對於不同的子查詢是不同的條件,所以你必須在每個子查詢中定義它。 –

+0

重複它沒有什麼不對的 –

+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) 

的替代橫向是嵌套查詢。

+0

一個優雅的解決方案。 – klin

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; 
+0

我想你需要定義員工類型?你能指出我'has_a_null_value(employee)'發送一行而不是表嗎? –

+0

「僱員」類型已經存在。該函數獲取一行作爲參數。 – klin

+0

你的意思已經存在?只是創建一個表員工也創建類型?我必須在這裏丟失一些東西 –

相關問題