我正在尝试查询多对多关系,以查看是否存在一个标签,但不存在另一个标签。我正在尝试通过一个简单的查询来做到这一点。
我已经问了几个朋友,并检查了堆栈溢出,似乎找不到找到尝试执行类似操作的人。我设置了一个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'
答案 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