SQL左连接查询问题

时间:2015-11-07 21:45:55

标签: sql one-to-many

我有以下表格

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查询(apple& pear& banana)

因此,在上表中,它只会返回John Smith'

由于

3 个答案:

答案 0 :(得分:2)

这是set-within-sets查询的示例。解决此问题的灵活方法是使用group byhaving

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

要获取名称,您将加入Users表。

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

答案 1 :(得分: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;

答案 2 :(得分: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);

如果您只是寻找那些特定的项目,这不起作用。如果还有其他可以购买的商品,并且您只是在寻找购买这些特定商品的用户,则必须采取类似于Gordon的方式,并对商品的购买次数进行更正。