簡體   English   中英

內部連接的SQL子查詢問題

[英]sql subquery issue with inner join

我的數據庫中有這些表:

游客 -這是第一張桌子

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。 這位ID為86的游客需要額外付費,其中Extra_Charge_ID-7和Extra_charge_ID-11;

我嘗試進行查詢,以便可以獲取Tourist的名稱以及EXTRA_CHARGES表中不屬於該Traveler的所有費用。

這是我嘗試的查詢-但不會返回任何內容。

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
 )

但我找不到找到這位游客名字的方法

您可以在選擇語句中將游客名稱(針對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
       )

您可以嘗試這樣做,這樣會更有效:

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列

您可以使用兩個選項,兩者幾乎相同,但是根據您的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小提琴示例

只需使用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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM