我的数据库中有这些表:
游客 - 这是第一张表
Tourist_ID - primary key
name...etc...
EXTRA_CHARGES
Extra_Charge_ID - primary key
Extra_Charge_Description
Amount
Tourist_Extra_Charges
Tourist_Extra_Charge_ID
Extra_Charge_ID - foreign key
Tourist_ID - foreign key
所以这是示例
我和Tourist_ID有一个游客 - 86。这位身份为86的游客使用Extra_Charge_ID - 7和Extra_charge_ID - 11收取额外费用;
我尝试进行查询,以便我可以将游客的名字和EXTRA_CHARGES表格中的所有费用不属于这位游客。
这是我尝试的查询 - 但它不会返回任何内容。
SELECT
Tourist.Name
, EXTRA_CHARGES.Extra_Charge_Description
, EXTRA_CHARGES.Amount
FROM
Tourist
INNER JOIN TOURIST_EXTRA_CHARGES
ON Tourist.Tourist_ID = TOURIST_EXTRA_CHARGES.Tourist_ID
INNER JOIN EXTRA_CHARGES
ON TOURIST_EXTRA_CHARGES.Extra_Charge_ID = EXTRA_CHARGES.Extra_Charge_ID
WHERE
Tourist.Tourist_ID= 86
and EXTRA_CHARGES.Extra_Charge_ID NOT IN
( SELECT Extra_Charge_ID
FROM TOURIST_EXTRA_CHARGES te
WHERE te.Tourist_ID = 86
)
我当然只能通过此查询获得收费
SELECT * FROM EXTRA_CHARGES e
WHERE e.Extra_Charge_ID NOT IN
(SELECT Extra_Charge_ID from TOURIST_EXTRA_CHARGES te
WHERE te.Tourist_ID = 86
)
但我无法找到获得这个游客名字的方法
答案 0 :(得分:1)
您可以在select语句中包含旅游名称(对于Tourist_ID = 86)作为子查询:
SELECT (SELECT Tourist.Name FROM Tourist WHERE Tourist_ID=86) TouristName, e.*
FROM EXTRA_CHARGES e
WHERE e.Extra_Charge_ID NOT IN
(SELECT Extra_Charge_ID
FROM TOURIST_EXTRA_CHARGES te
WHERE te.Tourist_ID = 86
)
答案 1 :(得分:1)
你可以尝试一下它的效率更高:
SELECT t.Name
FROM Tourist t JOIN
(SELECT * FROM EXTRA_CHARGES e
JOIN TOURIST_EXTRA_CHARGE tec ON e.Extra_Charge_ID = tec.Extra_Charge_ID AND tec.TOURIST_EXTRA_CHARGES != 86)
WHERE t.Tourist_ID = 86
顺便说一句。您不需要Tourist_Extra_Charges中的Tourist_Extra_Charge_ID列
答案 2 :(得分:1)
您可以使用两个选项,两者都非常相似,但one may perform better than the other取决于您的DBMS。
两者的原则是相同的,获得旅游和额外费用的交叉加入,因此您需要为所有游客收取所有额外费用,然后使用NOT EXISTS
或LEFT JOIN/IS NULL
来消除所有额外费用游客有:
SELECT Tourist.Name,
EXTRA_CHARGES.Extra_Charge_Description,
EXTRA_CHARGES.Amount
FROM Tourist
CROSS JOIN EXTRA_CHARGES
WHERE Tourist.Tourist_ID= 86
AND NOT EXISTS
( SELECT 1
FROM TOURIST_EXTRA_CHARGES
WHERE TOURIST_EXTRA_CHARGES.Tourist_ID = Tourist.Tourist_ID
AND TOURIST_EXTRA_CHARGES.Extra_Charge_ID = EXTRA_CHARGES.Extra_Charge_ID
);
SELECT Tourist.Name,
EXTRA_CHARGES.Extra_Charge_Description,
EXTRA_CHARGES.Amount
FROM Tourist
CROSS JOIN EXTRA_CHARGES
LEFT JOIN TOURIST_EXTRA_CHARGES
ON TOURIST_EXTRA_CHARGES.Tourist_ID = Tourist.Tourist_ID
AND TOURIST_EXTRA_CHARGES.Extra_Charge_ID = EXTRA_CHARGES.Extra_Charge_ID
WHERE Tourist.Tourist_ID = 86
AND TOURIST_EXTRA_CHARGES.Tourist_Extra_Charge_ID IS NULL;
修改强>
由于您应用的两个条件在逻辑上是不同的,因此您需要使用两个查询来获取它。第一个是和以前一样,游客没有额外收费,第二个是收取所有额外费用的游客
SELECT Tourist.Name,
EXTRA_CHARGES.Extra_Charge_Description,
EXTRA_CHARGES.Amount
FROM Tourist
CROSS JOIN EXTRA_CHARGES
LEFT JOIN TOURIST_EXTRA_CHARGES
ON TOURIST_EXTRA_CHARGES.Tourist_ID = Tourist.Tourist_ID
AND TOURIST_EXTRA_CHARGES.Extra_Charge_ID = EXTRA_CHARGES.Extra_Charge_ID
WHERE Tourist.Tourist_ID = 1
AND TOURIST_EXTRA_CHARGES.Tourist_Extra_Charge_ID IS NULL
UNION ALL
SELECT Tourist.Name,
NULL,
NULL
FROM Tourist
CROSS JOIN EXTRA_CHARGES
LEFT JOIN TOURIST_EXTRA_CHARGES
ON TOURIST_EXTRA_CHARGES.Tourist_ID = Tourist.Tourist_ID
AND TOURIST_EXTRA_CHARGES.Extra_Charge_ID = EXTRA_CHARGES.Extra_Charge_ID
WHERE Tourist.Tourist_ID = 1
GROUP BY Tourist.Name
HAVING COUNT(*) = COUNT(TOURIST_EXTRA_CHARGES.Tourist_Extra_Charge_ID);
<强> Example on SQL Fiddle 强>
答案 3 :(得分:0)
只需使用INNER JOIN ... ON .. <> ...
SELECT
Tourist.Name
, EXTRA_CHARGES.Extra_Charge_Description
, EXTRA_CHARGES.Amout
FROM
Tourist
INNER JOIN TOURIST_EXTRA_CHARGES
ON Tourist.Tourist_ID <> TOURIST_EXTRA_CHARGES.Tourist_ID
INNER JOIN EXTRA_CHARGES
ON TOURIST_EXTRA_CHARGES.Extra_Charge_ID = EXTRA_CHARGES.Extra_Charge_ID
WHERE
Tourist.Tourist_ID= 86