首页 > 解决方案 > 如何进行完全外部联接

问题描述

THEATRES使用设置大小THEATRES.NUMOFROWS, THEATRES.NUMOFCOLS,每个都SEAT.SEATNO被绑定到THEATRES.IDSHOWTIMES.ID被绑定到THEATRES.IDTICKET_ITEMS被绑定到SHOWTIMES.ID

我想通过使用 where 子句加入表来显示所有值showtime.id。我知道外部联接将在不匹配时显示 null,但我的查询仅显示一条记录。

SELECT 
    SHOWTIMES.ID AS SHOWTIMESID,
    SHOWTIMES.THEATREID,
    THEATRES.THEATRENAME,
    THEATRES.NUMOFROWS,
    THEATRES.NUMOFCOLS,
    SEAT.SEATNO AS SEATLABEL,
    SEAT.ROWID,
    SEAT.COLUMNID,
    TICKET_ITEMS.SEATNO,
    TICKET_ITEMS.TICKETCODE
FROM
    SHOWTIMES FULL OUTER JOIN TICKET_ITEMS ON SHOWTIMES.ID =TICKET_ITEMS.SHOWTIMESID
     FULL OUTER JOIN THEATRES ON SHOWTIMES.THEATREID = THEATRES.ID
     FULL OUTER JOIN SEAT ON SEAT.SEATNO = TICKET_ITEMS.SEATNO
WHERE
    SHOWTIMES.ID = 1

;

标签: sqlsql-server

解决方案


如果您使用任何一种,OUTER JOIN并且您引用了WHERE您需要处理的列中的NULLs。如果你不这样做,你把它JOIN变成一个隐含的INNER JOIN. 举个简单的例子:

WITH T1 AS(
    SELECT ID, SomeString
    FROM (VALUES(1,'abc'),(2,'def')) V(ID, SomeString)),
T2 AS(
    SELECT ID, fID, AnotherString
    FROM (VALUES(1,1,'asd'),(2,1,'asdased')) V(ID, fID, AnotherString))
SELECT *
FROM T1
     LEFT JOIN T2 ON T1.ID = T2.ID
WHERE T2.AnotherString = 'asd';

可能希望在此处获得 2 行,其中 1 行表示 where T1.IDis1有连接行,1 行表示T1.IDis 2,但没有连接行。情况并非如此,因为WHERE. 此处正确的解决方案是将WHERE移至ON

WITH T1 AS(
    SELECT ID, SomeString
    FROM (VALUES(1,'abc'),(2,'def')) V(ID, SomeString)),
T2 AS(
    SELECT ID, fID, AnotherString
    FROM (VALUES(1,1,'asd'),(2,1,'asdased')) V(ID, fID, AnotherString))
SELECT *
FROM T1
     LEFT JOIN T2 ON T1.ID = T2.ID
                 AND T2.AnotherString = 'asd';

有了你所拥有的,你不能这样做,因为你正在使用基表,因此你需要NULL通过改变你WHERE来处理:

WHERE SHOWTIMES.ID = 1 OR SHOWTIMES.ID IS NULL;

推荐阅读