2017-04-03 1 views
1

私は2つのpostgreSQLテーブルを持っています:従業員employee_carsです。 「BMW」、「MERC」、「VW」を所有するすべての従業員を出力する必要がありますが、「AUDI」ではありません。PostgreSQLの検索条件に行がないと出力する必要があります

Iは、クエリの下にしようとしている:以下

SELECT DISTINCT a.employee_name, b.car_brand 
FROM employees a 
LEFT JOIN employee_cars b 
ON a.employee_id = b.employee_id 
WHERE b.car_brand IN ('BMW','MERC','VW') 
AND b.car_brand NOT LIKE 'AUDI'; 

OUTPUT:

employee_name,car_brand 
"Mary","BMW" 
"Mary","MERC" 
"Mary","VW" 
"Paul","BMW" 
"Paul","MERC" 
"Paul","VW" 

問題は、従業員が所有する各車両はemployee_carsテーブルの行があることです。例えば、私には「BMW」、「MERC」、「VW」、「AUDI」を所有する「Mary」があります。 「BMW」、「MERC」、「VW」だけが所有する「Paul」があります。 「BMW」、「MERC」、「VW」の両方を所有しているため、私のクエリにMaryとPaulの両方が表示されます。

「アウディ」が不足しているため、私の検索結果に「Paul」が表示されます。

私はDBの専門家ではありませんので、ご協力いただきますようお願い申し上げます。 ありがとうございます。

+0

をああ、私は参照してください。 'BMW'、 'MERC' ** AND ** 'VW'は実際に 'BMW'、 'MERC' ** OR ** 'VW'を意味します。 –

+0

@Laurenz Albe、少し複雑ではない: ''BMW'、 'MERC'、 'VW'' ** AND NOT **'' AUDI'' – FireHawk2300

答えて

1

私は「BMW」を所有し、全従業員を出力する必要があります ' MERC 'AND' VW 'であるが、' AUDI 'ではない。あなたは従業員+車のブランドのペア、明瞭であることを従業員がいない必要がある場合は、集計でこれを行うことができます。

SELECT e.employee_name, string_agg(c.car_brand, ', ') 
FROM  employees e 
JOIN  employee_cars c ON e.employee_id = c.employee_id 
GROUP BY e.employee_id 
HAVING COUNT(1) FILTER (WHERE c.car_brand IN ('BMW', 'MERC', 'VW')) = 3 
AND  COUNT(1) FILTER (WHERE c.car_brand = 'AUDI') = 0 

これはまた、「BMW」、「MERC」のいずれかを持っていない従業員を、除外しますまたは 'VW'(あなたの質問と同様)。

http://rextester.com/MQL14836

編集:古いPostgreSQLのバージョンの代わりにFILTER INGのCASE表現を使用します。

SELECT e.employee_name, string_agg(c.car_brand, ', ') 
FROM  employees e 
JOIN  employee_cars c ON e.employee_id = c.employee_id 
GROUP BY e.employee_id 
HAVING COUNT(CASE WHEN c.car_brand IN ('BMW', 'MERC', 'VW') THEN 1 END) = 3 
AND  COUNT(CASE WHEN c.car_brand = 'AUDI' THEN 1 END) = 0 

http://rextester.com/KHMW56692

+0

私はこの解決策はうまくいくと考えていますが、FILTERING COUNTに問題があります。私はPGバージョン9.2を持っています。 – FireHawk2300

+0

@JP_CNTLM_ADMINあなたは 'COUNT(CASE ...)'を使うことができます。私はすぐに私の答えを更新します。 – pozs

+0

ありがとう!魅力のように動作します...あなたは、伝説です! – FireHawk2300

1

not exists状態でこれを組み合わせる:あなたが外を必要としない

注は、従業員とemployee_cars間の結合

+0

こんにちは@a_horse_with_no_name、あなたのフィードバックに感謝します。あなたの提案は素晴らしいです。問題は私とあなたのIN文であり、従業員だけが1台の車両を所有していてもクエリは結果を返します。たとえば、 "John" OnlyはBMWを所有しています。 3つのBMW、MERC、VWを所有する従業員だけを出力し、「AUDI」を出力する必要はありません。 – FireHawk2300

関連する問題