PostgreSQL 搜索条件必须输出丢失的行

PostgreSQL search criteria must output missing row

我有两个 postgreSQL 表,即:employeesemployee_cars。 我需要输出所有拥有 'BMW'、'MERC' 和 'VW' 但不是 'AUDI'.

的员工

我试过以下查询:

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';

输出如下:

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

问题是员工拥有的每辆车都是 employee_cars 表中的一行。例如;我有 'Mary',它拥有:'BMW'、'MERC'、'VW'、'AUDI'。 我有 'Paul',它只拥有:'BMW'、'MERC'、'VW'。 我的查询将显示 Mary 和 Paul,因为他们都拥有 'BMW'、'MERC'、'VW'。

我只想在结果中看到 'Paul',因为他缺少 'AUDI'。

请注意,我不是数据库专家,我将不胜感激任何帮助和帮助。 提前致谢。

将其与 not exists 条件相结合:

SELECT distinct emp.employee_name, ec.car_brand
FROM employees emp
  JOIN employee_cars ec ON emp.employee_id = ec.employee_id
WHERE ec.car_brand IN ('BMW','MERC','VW')
  and not exists (select *
                  from employee_cars ec2
                  where ec2.car_brand = 'AUDI'
                    and ec2.employee_id = emp.employee_id);

请注意,您不需要在员工和 employee_cars

之间进行外部联接

我需要输出所有拥有 'BMW'、'MERC' 和 'VW' 但不是 'AUDI'.[=29= 的员工] 如果你需要员工是不同的,而不是员工+汽车品牌对,你可以通过聚合来做到这一点:

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

Edit:对于较旧的 PostgreSQL 版本,使用 CASE 表达式而不是 FILTERing:

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