使用 NOT IN / NOT EXISTS(?) 和三个表的 SQL 查询的结构
Structure of SQL query using NOT IN / NOT EXISTS(?) with three tables
我需要帮助找出查询的正确结构
find the names of those clients, who stopped in exactly the same
hotels as John Doe.
我有桌子:
Clients(clientID, clientName)
ClientTour(clientID, tourID)
Tours(tourID, country, hotel)
全部写成一个查询。
我对 SQL 很陌生,不能为它写下正确的子查询,因为它使用三个表...我有点了解如何为两个表编写类似的查询,但是当我试着写这个……好吧,我迷路了。 =/
据我所知,我必须找到那些客户的名字,
谁停在
[John Doe 停靠的所有酒店] - [只有 John Doe 停靠的酒店]
但谁从未停止过那些
[李四从未下榻的酒店]。
逻辑上对吗?如果是,那么我得到的部分是
SELECT c1.clientName
FROM Clients c1
WHERE c1.clientID NOT IN (clientIDs of clients in [Hotels where John
Doe never stopped])
AND c1.clientID IN (clientIDs of clients in [[All Hotels where John
Doe stopped] - [Hotels where only John Doe stopped]])
但无法弄清楚以斜体标记的部分...我如何找到曾在 John Doe did/didn 未下榻的酒店或仅 John Doe 下榻的酒店下榻的客户?
另外,有没有更简单的方法来写下这个查询?
编辑:
1. 在外层SELECT增加了一个GROUP BY子句,取代了DISTINCT的需要,并在结果中为每个客户增加了countnig家酒店的选项设置。请注意,结果集仅包含 'John Doe' 入住过的酒店。
2. 添加了一个 SELECT 语句来计算 'John Doe' 访问过的酒店数量。
3. 添加了一个 HAVING 子句以从结果集中删除酒店数量不同于 'John Doe'.
的客户
SELECT C.clientName
FROM (Clients AS C INNER JOIN ClientTour AS CT ON C.clientID = CT.clientID) INNER JOIN Tours AS T ON CT.tourID = T.tourID
WHERE C.clientName <> 'John Doe'
AND T.hotel IN
(
SELECT DISTINCT T1.hotel
FROM (Clients AS C1 INNER JOIN ClientTour AS CT1 ON C1.clientID = CT1.clientID) INNER JOIN Tours AS T1 ON CT1.tourID = T1.tourID
WHERE C1.clientName = 'John Doe'
)
GROUP BY C.clientName
HAVING COUNT(DISTINKT T.hotel) = SELECT COUNT(DISTINCT T2.hotel)
FROM (Clients AS C2 INNER JOIN ClientTour AS CT2 ON C2.clientID = CT2.clientID) INNER JOIN Tours AS T2 ON CT2.tourID = T2.tourID
WHERE C2.clientName = 'John Doe'
第一次尝试:
SELECT C.clientName
FROM (Clients AS C INNER JOIN ClientTour AS CT ON C.clientID = CT.clientID) INNER JOIN Tours AS T ON CT.tourID = T.tourID
WHERE Trim(C.clientName) <> 'John Doe'
AND T.hotel IN
(
SELECT DISTINCT T1.hotel
FROM (Clients AS C1 INNER JOIN ClientTour AS CT1 ON C1.clientID = CT1.clientID) INNER JOIN Tours AS T1 ON CT1.tourID = T1.tourID
WHERE Trim(C1.clientName) = 'John Doe'
)
我需要帮助找出查询的正确结构
find the names of those clients, who stopped in exactly the same hotels as John Doe.
我有桌子:
Clients(clientID, clientName)
ClientTour(clientID, tourID)
Tours(tourID, country, hotel)
全部写成一个查询。
我对 SQL 很陌生,不能为它写下正确的子查询,因为它使用三个表...我有点了解如何为两个表编写类似的查询,但是当我试着写这个……好吧,我迷路了。 =/
据我所知,我必须找到那些客户的名字, 谁停在
[John Doe 停靠的所有酒店] - [只有 John Doe 停靠的酒店]
但谁从未停止过那些
[李四从未下榻的酒店]。
逻辑上对吗?如果是,那么我得到的部分是
SELECT c1.clientName
FROM Clients c1
WHERE c1.clientID NOT IN (clientIDs of clients in [Hotels where John Doe never stopped])
AND c1.clientID IN (clientIDs of clients in [[All Hotels where John Doe stopped] - [Hotels where only John Doe stopped]])
但无法弄清楚以斜体标记的部分...我如何找到曾在 John Doe did/didn 未下榻的酒店或仅 John Doe 下榻的酒店下榻的客户?
另外,有没有更简单的方法来写下这个查询?
编辑:
1. 在外层SELECT增加了一个GROUP BY子句,取代了DISTINCT的需要,并在结果中为每个客户增加了countnig家酒店的选项设置。请注意,结果集仅包含 'John Doe' 入住过的酒店。
2. 添加了一个 SELECT 语句来计算 'John Doe' 访问过的酒店数量。
3. 添加了一个 HAVING 子句以从结果集中删除酒店数量不同于 'John Doe'.
SELECT C.clientName
FROM (Clients AS C INNER JOIN ClientTour AS CT ON C.clientID = CT.clientID) INNER JOIN Tours AS T ON CT.tourID = T.tourID
WHERE C.clientName <> 'John Doe'
AND T.hotel IN
(
SELECT DISTINCT T1.hotel
FROM (Clients AS C1 INNER JOIN ClientTour AS CT1 ON C1.clientID = CT1.clientID) INNER JOIN Tours AS T1 ON CT1.tourID = T1.tourID
WHERE C1.clientName = 'John Doe'
)
GROUP BY C.clientName
HAVING COUNT(DISTINKT T.hotel) = SELECT COUNT(DISTINCT T2.hotel)
FROM (Clients AS C2 INNER JOIN ClientTour AS CT2 ON C2.clientID = CT2.clientID) INNER JOIN Tours AS T2 ON CT2.tourID = T2.tourID
WHERE C2.clientName = 'John Doe'
第一次尝试:
SELECT C.clientName
FROM (Clients AS C INNER JOIN ClientTour AS CT ON C.clientID = CT.clientID) INNER JOIN Tours AS T ON CT.tourID = T.tourID
WHERE Trim(C.clientName) <> 'John Doe'
AND T.hotel IN
(
SELECT DISTINCT T1.hotel
FROM (Clients AS C1 INNER JOIN ClientTour AS CT1 ON C1.clientID = CT1.clientID) INNER JOIN Tours AS T1 ON CT1.tourID = T1.tourID
WHERE Trim(C1.clientName) = 'John Doe'
)