2

我的数据库中有这些表:

游客- 这是第一张桌子

Tourist_ID - primary key
name...etc...

额外收费

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 的 Tourist。这位 ID 为 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
 )

但我找不到这个游客的名字

4

4 回答 4

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 列

于 2013-08-16T09:47:55.110 回答
1

您可以使用两个选项,两者几乎相同,但根据您的 DBMS ,一个可能比另一个执行得更好。

两者的原则是相同的,获得游客和额外费用的交叉连接,因此您对所有游客都有所有额外费用,然后使用NOT EXISTSLEFT 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);

SQL Fiddle 示例

于 2013-08-16T09:52:35.900 回答
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
       )
于 2013-08-16T09:40:03.460 回答
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 

见这里: http ://sqlfiddle.com/#!2/28665/2

于 2013-08-16T09:45:12.567 回答