2010-03-26 30 views
3

我已經使用MySQL 2年了,但我仍然不知道你實際上用JOIN聲明做了什麼。我真的沒有遇到任何情況從哪裏來我無法解決與語句和語法問題,我已經知道(SELECTINSERTUPDATE,排序,...)什麼是SQL(for)中的JOIN?

  • 是什麼做的JOIN在MySQL ?
  • (哪裏)我需要它嗎?
  • 我應該通常避免它嗎?每當 我們必須從2個或更多 表選擇數據
+6

JOIN的視覺解釋:http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html – 2010-03-26 16:12:31

+1

@OMG Ponies - OMG Charts! – DVK 2010-03-26 16:25:42

+0

這裏有一篇很好的文章,解釋了不同類型以及何時使用每一種類型:http://www.devshed.com/c/a/MySQL/Understanding-SQL-Joins/ – Leslie 2010-03-26 16:35:59

回答

7

你可能一直在使用它不知道它,如果你曾經在一次查詢多個表。

如果你喜歡

SELECT comment_text 
FROM users, comments 
WHERE users.user_id = 'sabwufer' 
AND comments.user_id = users.user_id <-- this line is your JOIN condition 

查詢然後你,其實,做一個連接(內部聯接),即使你不使用join關鍵字。

(旁白:上面的查詢是

SELECT comment_text 
FROM users 
JOIN comments ON (comments.user_id = users.user_id) 
WHERE users.user_id = 'sabwufer' 

等效)

如果你做的是內部聯接,那麼你就需要使用JOIN關鍵字,但它可以使你做得更清楚。

但是,還有其他有用的連接類型(例如,請參閱教程XpiritO鏈接),並且它們值得理解。

+0

這種語法不會產生CROSS JOIN默認?與INNER JOIN的區別有點微妙,但如果在不理解WHERE子句的(可選)角色的情況下加入大表,這一點可能很重要。 – harpo 2010-03-26 16:28:46

+1

我不確定你的意思是「這個語法」,但不是,如果你指定了一個連接條件,那麼你沒有做一個CROSS JOIN。當然,'SELECT * FROM users,comments'本身就是一個隱含的CROSS JOIN,但是添加WHERE子句會使它成爲一個隱式的INNER JOIN。 – 2010-03-26 16:34:42

+0

我看...謝謝澄清。 – harpo 2010-03-26 16:50:40

7

的SQL JOIN子句被使用。

爲了能夠使用SQL從2(或多個)表JOIN子句 提取數據, 我們需要在這些表中的某些列 之間的關係。

源(檢查了這一點的例子):

假設你有一個用戶表:

Customer_ID 
FirstName 
LastName 
... 

http://www.sql-tutorial.net/SQL-JOIN.asp

1

爲了一個具體的例子擴大@ XpiritO的答案和一張訂單表。

Order_ID 
Customer_ID 
(description) 

給定一個訂單ID,你想獲取客戶的名字。所以:

select top 1 tbl_customer.* from tbl_customers inner join tbl_orders on tbl_orders.customer_id = tbl_customers.id and tbl_orders.id={the order id you started with}. 

你會得到一個結果集,看起來像

customer_id first_name last_name order_id description 
3

如果您不必定期使用JOINS,那麼您的數據庫設計就不太好,並且有很多冗餘。

JOINS允許您(如XpiritO)所說,從2個或更多表中選擇數據。當你有一個帶有外鍵的表(對另一個表中的一行數據的引用)時,這是非常重要的。

例如,假設你有一個客戶表具有以下數據:

firstName, lastName, customerId, address 

在哪裏「客戶ID」是對每一個客戶的關鍵。然後說你有一個產品表:

category, name, price, productId 

其中ProductID等於該產品的關鍵。

然後你可以有一個購買表:

customerId, productId 

如果你跟蹤一個客戶買什麼樣的產品。使用JOIN語句,您可以查詢數據庫中客戶購買哪些產品或購買什麼產品。此外,還可以存儲有關對採購表,購買更多的信息,如購買時,使用折扣等

示例查詢是:

SELECT * FROM Customer INNER JOIN Purchases on Customer.customerID=Purchases.customerID 
+0

大衛看起來像一個非常相似的例子打敗我。 :P – 2010-03-26 16:19:34

3

你不應該回避它—你應該擁抱它。如果您還沒有使用JOIN,那麼您的數據庫可能不是normalizing

下面是一個簡單的例子。說你有這個表

play_id play_title     play_category 
1  All's Well That Ends Well Comedy 
2  As You Like It    Comedy 
3  Antony and Cleopatra  Tragedy 
4  Cymbeline     Romance 
5  Henry IV, Part 1   History 
6  Henry IV, Part 2   History 

可以查詢這個整天沒JOIN。但是,數據不是「標準化」的,這意味着你有冗餘。注意「喜劇」和「歷史」是如何重複的。存儲這些標籤更合適的方式是在一個專用表:

play_category_id play_category_name 
1     Comedy 
2     Tragedy 
3     History 
4     Romance 

現在你可以「正常化」的打表,

play_id play_title     play_category 
1  All's Well That Ends Well 1 
2  As You Like It    1 
3  Antony and Cleopatra  2 
4  Cymbeline     4 
5  Henry IV, Part 1   3 
6  Henry IV, Part 2   3 

這不僅是更有效,它可以減少錯誤易發。

問題是,你如何回到顯示有意義標籤的視圖。 (因爲我們更換一個有意義場任意鍵,play_category_id。)

這是JOIN進來。

SELECT play_id, play_title, play_category_name 
    FROM play 
    LEFT OUTER JOIN play_category ON play_category = play_category_id 

還有很多東西要加入的力學和藝術,但根本原因一般歸結爲這種情況。

希望這會有所幫助。

+0

Harpo - 關於規範化的好點子,但如果你真的很狡猾,如果你使用嵌套選擇,你可以在規範化表格上沒有JOIN的情況下得到相同的結果 - 但這是更多的工作,而且有點蹩腳。 – konung 2010-03-26 16:28:34

+0

@尼克,正確。我沒有提到子查詢或表值函數,以便專注於OP的問題。 – harpo 2010-03-26 16:51:37

0

這裏是一個例子。

假設你有一個帶有作者的表格和一個帶有書籍的表格。

你可以這樣做:

SELECT * FROM authors LEFT JOIN books ON authors.id = books.author_id 

這將產生從

SELECT * FROM authors, books WHERE authors.id = books.author_id 

不同的結果在加入您參與的結果集即使是那些沒有任何圖書的作者獲得的情況下,就第二種說法而言,你只能得到那些在書籍表中有書的作者。它可能看不出什麼大不了的,但是根據與客戶和付款的表來考慮這一點。

如果您進行加入 - 如果您執行第二種選擇,您將能夠看到所有客戶,即使那些沒有任何付款的客戶 - 您將看不到任何沒有付款的客戶。你可以通過運行

SELECT * FROM authors, books WHERE authors.id <> books.author_id 

SELECT * FROM authors WHERE authors.id NOT IN (SELECT DISTINCT(books.author_id) FROM books) 

這些都是有效的方法來獲取數據找到他們 - 但他們提供了從加入不同的效果,如果你明白 - 那麼不使用連接爲我猜好的 - 但是你正在限制自己 - 而且這些方法在大多數使用情況下都比較慢。

0

正如其他人已經說過,當您需要依賴另一個表中的信息的信息時,INNER JOIN頻繁出現。還有其他有效的點,例如標準化。如果您問是否有任何與JOIN語法有關的問題,請嘗試執行OUTER JOIN。