2017-08-03 1 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(従業員)'がテーブルの代わりに行を送る方法を教えてもらえますか? –

+0

タイプ 'employee'は既に存在します。関数は引数として行を取得します。 – klin

+0

あなたはすでに何かを意味していますか?テーブルの従業員を作成するだけで、タイプが作成されますか? Imはここで何かが欠けているはずです –

関連する問題