Sql-Server

了解多個連接的變化

  • January 20, 2021

我有兩個版本的多重連接,它們產生相同的結果。五張表分別是:

customers ← sales ← saleitems → paintings → artists

箭頭(希望)顯示了表之間的關係。

每個表都有一個名為 的主鍵id,而內部表有一個指向另一個名為 的表的外鍵[othertable]id

第一個版本是按上述順序列出的表的經典連接

SELECT
   c.id, c.givenname, c.familyname,
   a.givenname, a.familyname
FROM
   customers c
       JOIN sales s ON c.id=s.customerid
           JOIN saleitems si ON s.id=si.saleid
               JOIN paintings p ON si.paintingid=p.id
                   JOIN artists a ON p.artistid=a.id

;

第二個版本JOIN首先是所有子句,然後是ON子句,順序相反

SELECT
   c.id, c.givenname, c.familyname,
   a.givenname, a.familyname
FROM
   customers c
       JOIN sales s 
           JOIN saleitems si
               JOIN paintings p
                   JOIN artists a
                   ON p.artistid=a.id
               ON si.paintingid=p.id
           ON s.id=si.saleid
       ON c.id=s.customerid

;

好的,所以它可以工作,但是任何人都可以解釋第二個版本是如何工作的嗎?為什麼子句的順序必須與ON子句相反JOIN?是否可以隨機排序JOINorON子句?

我已經在 Microsoft SQL 以及 PostgreSQL 中對此進行了測試。

你不能隨機化它們,順序很重要。如果我們在連接之間添加一些括號,也許您可以更清楚地看到它。

SELECT
   c.id
FROM
   customers c
       JOIN (sales s JOIN saleitems si ON s.id = si.saleid)
   ON c.id = s.customerid

這個查詢正在做的是首先加入salessaleitems然後他們的結果被加入customers。您不能引用customers括號連接內的列,因為它不可訪問:

SELECT
   c.id
FROM
   customers c
       JOIN (sales s JOIN saleitems si ON s.id = si.saleid 
           AND c.id = c.customerid) -- What is c.customerid here??

消息 4104,級別 16,狀態 1,第 6 行 無法綁定多部分標識符“s.customerid”。

如果你問我,我會堅持使用第一種編寫查詢的方式,這種方式對大多數程序員來說更清晰。

引用自:https://dba.stackexchange.com/questions/210813