union用法 - sql同時查詢兩個資料表




INNER JOIN ON與WHERE子句 (7)

為了簡單起見,假定所有相關字段都不是NOT NULL

你可以做:

SELECT
    table1.this, table2.that, table2.somethingelse
FROM
    table1, table2
WHERE
    table1.foreignkey = table2.primarykey
    AND (some other conditions)

要不然:

SELECT
    table1.this, table2.that, table2.somethingelse
FROM
    table1 INNER JOIN table2
    ON table1.foreignkey = table2.primarykey
WHERE
    (some other conditions)

這兩個工作是否在MySQL以相同的方式工作?


ANSI連接語法絕對更具可移植性。

我正在經歷Microsoft SQL Server的升級,並且我還會提及2005 SQL Server及其後版本不支持SQL Server中外部連接的= *和* =語法(沒有兼容模式)。


SQL:2003標準改變了一些優先規則,所以JOIN語句優先於“逗號”連接。 這實際上可以根據設置的方式更改查詢結果。 當MySQL 5.0.12切換到遵循標準時,這對一些人造成了一些問題。

因此,在你的例子中,你的查詢將是一樣的。 但是,如果您添加了第三個表格:SELECT ... FROM table1,table2 JOIN table3 ON ... WHERE ...

在MySQL 5.0.12之前,table1和table2會先加入,然後再加入table3。 現在(5.0.12和之後),table2和table3先聯合,然後聯合table1。 它並不總是改變結果,但它可以,你甚至可能沒有意識到它。

我從不再使用“逗號”語法,選擇你的第二個例子。 無論如何,它的可讀性要高得多,JOIN條件與JOIN相同,而不是單獨的查詢部分。


INNER JOIN是您應該使用的ANSI語法。

它通常被認為更具可讀性,尤其是當您加入大量表格時。

只要需要,它也可以很容易地用OUTER JOIN替換。

WHERE語法更多地是以關係模型為導向的。

兩個JOIN ed表的結果是應用過濾器的表的笛卡爾積,該過濾器僅選擇具有匹配的連接列的那些行。

WHERE語法來看這很容易。

至於你的例子,在MySQL(通常是SQL)中,這兩個查詢是同義詞。

另請注意,MySQL也有一個STRAIGHT_JOIN子句。

使用此子句,您可以控制JOIN順序:在外部循環中掃描哪個表格,以及哪個表格在內部循環中。

你無法使用WHERE語法在MySQL中進行控制。


其他人指出,INNER JOIN有助於人類的可讀性,這是重中之重; 我同意。 讓我試著解釋為什麼連接語法更具可讀性。

一個基本的SELECT查詢是這樣的:

SELECT stuff
FROM tables
WHERE conditions

SELECT子句告訴我們我們回來了什麼 ; FROM子句告訴我們從哪裡得到它,而WHERE子句告訴我們我們得到了哪些東西。

JOIN是關於這些表格的陳述,它們是如何綁定在一起的(概念上,實際上,放入單個表格中)。 任何控製表的查詢元素(我們從中獲取東西的語義)都屬於FROM子句(當然,這就是JOIN元素去的地方)。 將連接元素放入WHERE子句中將哪些哪裡來自 ; 這就是為什麼JOIN語法是首選。


我知道你在談論MySQL,但無論如何:在Oracle 9中,顯式連接和隱式連接會生成不同的執行計劃。 已經在Oracle 10+中解決的AFAIK:再也沒有這種差異了。


我還會指出,使用舊的語法更容易出錯。 如果使用沒有ON子句的內部連接,則會出現語法錯誤。 如果使用較舊的語法並忘記where子句中的某個連接條件,則會得到一個交叉連接。 開發人員通常通過添加distinct關鍵字(而不是修復連接,因為他們仍然沒有意識到連接本身已被破壞)來解決此問題,這似乎可以解決問題,但會大大減慢查詢速度。

另外為了維護,如果你有舊的語法的交叉連接,維護人員如何知道你是否打算有一個(有需要交叉連接的情況),或者如果這是一個應該修復的事故?

讓我來看看這個問題,看看為什麼如果使用左連接,隱式語法是不好的。 對於相同的內部表,Sybase * =帶有兩個不同外部表的Ansi Standard

再加上(個人咆哮),使用顯式連接的標準已超過20年,這意味著隱式連接語法已經過去20年了。 你會使用已經過時20年的語法來編寫應用程序代碼嗎? 你為什麼要編寫數據庫代碼?


隱式連接ANSI語法較舊,不太明顯,不推薦。

另外,關係代數允許謂詞在WHERE子句和INNER JOIN互換,所以即使是使用WHERE子句的INNER JOIN查詢也可以使優化器重新排列謂詞。

我建議你盡可能以最可讀的方式編寫查詢。

有時候,這包括使INNER JOIN相對“不完整”,並將一些條件放在WHERE只是簡單地使過濾條件列表更容易維護。

例如,而不是:

SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
    ON ca.CustomerID = c.CustomerID
    AND c.State = 'NY'
INNER JOIN Accounts a
    ON ca.AccountID = a.AccountID
    AND a.Status = 1

寫:

SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
    ON ca.CustomerID = c.CustomerID
INNER JOIN Accounts a
    ON ca.AccountID = a.AccountID
WHERE c.State = 'NY'
    AND a.Status = 1

但是,這取決於,當然。





inner-join