2015-11-07 129 views
0

我有以下表SQL LEFT JOIN查询问题

Users 
ID Name 
1 John Smith 
2 James Jones 
3 Peter Brown 

Purchases 
USERID NAME 
1  Apple 
1  Pear 
1  Banana 
2  Apple 
2  Pear 
3  Apple 

我怎么能有一个SQL查询,返回带来的用户(苹果&梨&香蕉)

所以它上面的表格中'John Smith'

谢谢

回答

2

这是一个set-set-set查询的例子。解决这个灵活的方法是使用group byhaving

select userid 
from purchases 
where name in ('apple', 'pear', 'banana') 
group by userid 
having count(*) = 3; 

要获取的名字,你会加入在Users表。

如果与样本数据不同,表中允许有重复项,则在having子句中使用count(distinct name) = 3

+1

是的,但如果一个人多次购买,则计数将提供虚假匹配。例如,如果用户'2'购买了另一个'梨',他的计数为3,即使他只买了两件。因此,你希望在某处有一个'distinct',或者另一个'select * from purchase group by userid,name' – vol7ron

0

SQL Fiddle

SELECT users.name, purchased.items 
FROM users 
INNER JOIN (
    select userid as id, array_agg(distinct name) items 
    from purchases 
    group by userid 
    having array_length(array_agg(distinct name),1)=3 
) purchased USING(id); 

,如果你只寻找那些具体项目这是行不通的。如果还有其他物品可以购买,而您只是在寻找购买这些特定物品的用户,那么您需要做一些类似于戈登的物品,并对物品的购买次数进行更正。

1

您可以JOIN表和COUNT产品:

SELECT u.Name 
FROM Purchases p 
JOIN Users u 
    ON p.UserID = u.ID 
WHERE p.Name IN ('Apple', 'Pear', 'Banana') 
GROUP BY userid 
HAVING COUNT(DISTINCT p.Name) = 3; 

SqlFiddleDemo

有可能是用户已经购买了2个苹果和一根香蕉,所以你应该算作不同的产品名称。

如果您正在使用Postgresql/SQL Server/Oracle你需要用Name与聚合函数:

SELECT MAX(u.Name) AS Name 
FROM Purchases p 
JOIN Users u 
    ON p.UserID = u.ID 
WHERE p.Name IN ('Apple', 'Pear', 'Banana') 
GROUP BY userid 
HAVING COUNT(DISTINCT p.Name) = 3;