SQL查询以选择在同一列中具有不同值的子记录的父级

Posted

技术标签:

【中文标题】SQL查询以选择在同一列中具有不同值的子记录的父级【英文标题】:SQL Query to select parent that has child records with different values in the same column 【发布时间】:2015-05-23 11:00:47 【问题描述】:

此数据库具有一对多的关系,其中父表 Customers 是客户列表,子表 Orders 是他们购买的东西的列表。我正在尝试开发一个查询来选择同时购买了电视和沙发的客户。以下查询返回 0 个结果。

SELECT Customer.*
FROM Customer
JOIN Orders
ON Customer.ID = Orders.customerID
WHERE Orders.item = 'television'
AND Orders.item = 'couch';

将 AND 替换为 OR 不起作用,因为它会返回同时购买了两种商品或仅购买其中一种商品的客户。我的目标结果是同时购买了两者的客户。

【问题讨论】:

【参考方案1】:

您需要利用子查询(或联合),您使用的是哪种 sql?

SELECT *
FROM CUSTOMER c
WHERE EXISTS (SELECT 1 FROM ORDERS o WHERE c.id = o.id and type = 'couch')
  and EXISTS (SELECT 1 FROM ORDERS o WHERE c.id = o.id and type = 'tv')

【讨论】:

谢谢!这行得通。我什至不知道“存在”声明。 (我还是 mysql 新手。)【参考方案2】:

我不是 MySQL 用户,但我从 SO 中了解到许多查询可能很慢。以下是只需要一个子查询的选项。

SELECT *
FROM CUSTOMER c
WHERE (
    SELECT COUNT(DISTINCT o.type) FROM ORDERS o
    WHERE o.id = c.id AND o.type IN ('couch', 'tv')
) = 2

SELECT *
FROM CUSTOMER c
WHERE c.id IN (
    SELECT o.id FROM ORDERS o
    WHERE o.type IN ('couch', 'tv')
    GROUP BY o.id
    HAVING MIN(o.type) <> MAX(o.type) -- or COUNT(DISTINCT o.type) = 2
)

【讨论】:

SELECT * FROM CUSTOMER c WHERE EXISTS (SELECT 1 FROM ORDERS o WHERE c.id = o.id and type IN ('tv','couch')) 是另一种编写查询的方式 行 o.id=c.id 将过滤掉任何连接。 exists 函数可以帮助您在没有 group by 子句和额外比较的情况下度过难关。 @discosammy 这是七岁。但乍一看,您的第一个查询并不等同。我完全知道如何使用group byexists

以上是关于SQL查询以选择在同一列中具有不同值的子记录的父级的主要内容,如果未能解决你的问题,请参考以下文章

SQL查询以选择具有最小值的不同行

需要 SQL 在不同的列中查找具有重复值的记录

编写 SQL 查询,选择除同时在三列中具有指定值的行之外的所有行

SQL 选择以消除在下一列中具有 2 个其他值的重复值

SQL如何查询出某一列中不同值出现的次数?

为啥在 oracle SQL 中,在条件相差很大的情况下,对同一列执行具有两个不同值的查询所花费的时间