我有三个表(Users,Items,UserItems),其中UserItems是Users和Items之间的多对多关系。我需要的是一个获取用户没有的所有项目的查询。
我在这里创建了一个带有一些假数据的SQL Fiddle示例:http://sqlfiddle.com/#!6/a6856/1
CREATE TABLE Users ( userID INT, firstName NVARCHAR(50) )
CREATE TABLE Items ( itemID INT, itemName NVARCHAR(50) )
CREATE TABLE UserItems ( userID INT, itemID INT )
INSERT INTO Users ( userID, firstName )
VALUES ( 1, 'Jack' ), ( 2, 'Jill' ), ( 3, 'John' ), ( 4, 'Jane' );
INSERT INTO Items ( itemID, itemName )
VALUES ( 1, 'Bucket' ), ( 2, 'Water' ), ( 3, 'Cast' );
INSERT INTO UserItems ( userID, itemID )
VALUES ( 1, 1 ), ( 1, 2 ), ( 1, 3 ), ( 2, 3 );
期望的结果用户和他们没有的物品:
---------------------------------
| userID | firstName | itemName |
|--------|-----------|----------|
| 2 | Jill | Bucket |
| 2 | Jill | Water |
| 3 | John | Bucket |
| 3 | John | Water |
| 3 | John | Cast |
| 4 | Jane | Bucket |
| 4 | Jane | Water |
| 4 | Jane | Cast |
---------------------------------
注意:Jack不需要在结果中,因为他有三个项目。
答案 0 :(得分:4)
select *
from Users as u inner join Items as i on 1=1
where not exists(select 0 from UserItems as ui where ui.userID=u.userID and i.itemID=ui.itemID)
order by userID,firstName,itemID
+--------+-----------+--------+----------+ | userID | firstName | itemID | itemName | +--------+-----------+--------+----------+ | 2 | Jill | 1 | Bucket | | 2 | Jill | 2 | Water | | 3 | John | 1 | Bucket | | 3 | John | 2 | Water | | 3 | John | 3 | Cast | | 4 | Jane | 1 | Bucket | | 4 | Jane | 2 | Water | | 4 | Jane | 3 | Cast | +--------+-----------+--------+----------+
答案 1 :(得分:1)
这看起来像是EXCEPT运算符的一个很好的用例。
SELECT U.UserID, I.itemID
FROM Users U
CROSS JOIN Items I -- Gets a set of all users and all items
EXCEPT
SELECT UI.UserID, UI.ItemID
FROM UserItems UI -- Removes the items that a user has.
答案 2 :(得分:1)
SELECT u.userId, u.firstName, i.itemId, i.itemName
FROM users u CROSS JOIN items i
LEFT OUTER JOIN useritems ui
ON u.userID = ui.userId AND i.itemId = ui.itemId
WHERE ui.itemId IS NULL
ORDER BY 1, 3;
答案 3 :(得分:0)
NOT EXISTS
似乎非常适合
SELECT
usr.userID
, usr.firstName
, itm.itemName
FROM
Users usr
, Items itm
WHERE NOT EXISTS
(
SELECT *
FROM UserItems usrItm
WHERE
usrItm.itemID = itm.itemID
AND usrItm.userID = usr.userID
)
ORDER BY
usr.userID
, itm.itemID