查询多对多关系以查看是否存在一个值,但不存在另一个值?

时间:2019-06-11 19:06:39

标签: mysql

我正在尝试查询多对多关系,以查看是否存在一个标签,但不存在另一个标签。我正在尝试通过一个简单的查询来做到这一点。

我已经问了几个朋友,并检查了堆栈溢出,似乎找不到找到尝试执行类似操作的人。我设置了一个SQLFiddle页面,其中显示了我要执行的操作。

http://sqlfiddle.com/#!9/22b741b/8

在该示例中,我有三个用户:Mike,Alice和George。
我有7条糖果:士力架,好时,银河,奇巧,里斯,提兹勒和酸辣酱。
Mike喜欢Snickers,KitKat,Reeses和Twizzlers。
爱丽丝喜欢KitKat,Hersheys和Sour Patch。
乔治喜欢KitKat和Twizzlers。

我想找出谁喜欢Twizzler,但不喜欢士力架。

这是我到目前为止的代码。有了这个,我得到了麦克和乔治。我只想要乔治。如何修改查询以使我得到所需的结果?

SELECT Users.firstname, Candy.candyname
FROM Users
INNER JOIN UsersCandy ON Users.id = UsersCandy.user_id
INNER JOIN Candy ON UsersCandy.candy_id = Candy.id
WHERE Candy.candyname = 'Twizzlers'
AND Candy.candyname != 'Snickers'

1 个答案:

答案 0 :(得分:1)

您的查询正在测试同一行中的candyname。如果糖果是Twizzlers,那么显然也不是Snickers。因此,您的查询只是找到所有喜欢Twizzlers的人。

写一个子查询,查找所有喜欢士力架的用户。然后将其与查找喜欢Twizzlers的用户的查询一起加入。第二个联接必须为LEFT JOIN,因此您可以测试NULL来查找不匹配的行,如Return row only if value doesn't exist所示。

SELECT DISTINCT u.firstname
FROM Users AS u
JOIN UsersCandy AS uc1 ON u.id = uc1.user_id
JOIN Candy AS c1 ON uc1.candy_id = c1.id
LEFT JOIN (
  SELECT u.id
  FROM Users AS u
  JOIN UsersCandy AS uc2 ON u.id = uc2.user_id
  JOIN Candy AS c2 ON uc2.candy_id = c2.id
  WHERE c2.candyname = 'Snickers'
) AS u2
  ON u.id = u2.id
WHERE c1.candyname = 'Twizzlers' AND u2.id IS NULL

DEMO