SQL WHERE子句匹配两个(或更多)连接的行

时间:2016-07-26 14:15:08

标签: sql postgresql

让我们假设这些表:

customer with age column
order with customer_id and item_id column

我需要这样的SELECT语句:

SELECT ... FROM customer c 
   JOIN order o ON c.id = o.customer_id
   WHERE c.age > 30 
   AND (c has ordered item_id 1 AND item_id 2)

订单表

中的每个订购商品都有一行

2 个答案:

答案 0 :(得分:2)

它将返回订购item_id 1 and 2

的客户
SELECT c.id 
FROM customer c 
JOIN order o ON c.id = o.customer_id
WHERE c.age > 30 AND o.item_id IN (1, 2)
GROUP BY c.id 
HAVING COUNT(DISTINCT o.item_id) = 2

示例执行:

CREATE TABLE Customer (Id VARCHAR (200), Age INT);
INSERT INTO Customer (Id, Age) VALUES (1, 25), (2, 31), (3, 35), (4, 40);

CREATE TABLE Order (customer_id VARCHAR (200), item_id INT);
INSERT INTO Order(customer_id, item_id) VALUES
(1, 1), (1, 2), (2, 1), (2, 2), (3, 1), (4, 2), (4, 1), (4, 3);

SELECT c.Id 
FROM customer c 
JOIN order o ON c.id = o.customer_id
WHERE c.age > 30 AND o.item_id IN (1, 2)
GROUP BY c.Id
HAVING COUNT(DISTINCT o.item_id) = 2

结果:

Id
----
2
4

答案 1 :(得分:2)

最有效的方法可能是:

select c.*
from customer c
where c.age > 30 and
      exists (select 1 from orders o where c.id = o.customer_id and o.item_id = 1) and
      exists (select 1 from orders o where c.id = o.customer_id and o.item_id = 2) ;

这可以利用customer(age, id)orders(customer_id, item_id)上的索引。请注意,在表格中存储年龄通常是不合理的,因为年龄一直在变化。