union用法 - sql同時查詢兩個資料表
INNER JOIN ON與WHERE子句 (7)
ANSI連接語法絕對更具可移植性。
我正在經歷Microsoft SQL Server的升級,並且我還會提及2005 SQL Server及其後版本不支持SQL Server中外部連接的= *和* =語法(沒有兼容模式)。
為了簡單起見,假定所有相關字段都不是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
以相同的方式工作?
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
但是,這取決於,當然。