2015-12-08 100 views
1

假設我有兩個表Gardners tablePlantings tableSQL連接如何實際工作?

enter image description here

假設我的查詢是:

SELECT gid, first_name, last_name, pid, gardener_id, plant_name 
FROM Gardners 
INNER JOIN Plantings 
ON gid = gardener_id 

我想知道它究竟是如何工作的內部?

按我的理解,在每一個join條件:

  • Gardner Table每一行都將與Plantings Table每一行進行比較。如果條件匹配,則會打印出來。我的理解是否正確?

在程序方面,如果你認爲:

for i in [Gardners Table]: 
    for j in [Plantings Table]: 
     if i.id == j.garderner id: 
      print <> 

現在假設,如果你的查詢是一樣的東西:

User(uid,uname,ucity,utimedat) 
Follows(uid,followerid) // uid and followerid are pointing to `uid` of `User`. 

SELECT U.uid, U.uname FROM User U1 JOIN Follows F,User U2 WHERE 
    F.followerid = U2.uiddate AND U2.ucity = 'D' 

如何連接條件,將內部工作在這裏嗎?是不是等同於:

for i in [USER]: 
     for j in [Follows]: 
      for k in [USER]: 
      if condition: 
       print <> 
+0

你的理解似乎是正確的。但是我會清理你的查詢來使用別名,以便清楚每列所屬的表。 –

+0

您能否看到我的更新! – python

+0

尋找將用於選擇和連接的算法。你能否詳細說明這個意義! – python

回答

2

您與Gardners tablePlantings table例子是正確的。但users的例子並不那麼明顯。

我認爲你想得到的是來自某個城市的用戶追隨者。

假設正確的查詢是:

SELECT U1.uid, U2.uname 
FROM User U1 
    JOIN Follows F ON U1.uid = F.uid 
    JOIN User U2 ON F.followerid = U2.uid 
WHERE U2.ucity = 'D' 

然後在僞代碼,它會是這樣的:

for i in [User Table]: 
    for j in [Follows Table]: 
    if i.uid = j.uid: 
     for k in [User Table]: 
     if j.followerid = k.uid and k.city = 'D': 
      print <> 

SQL搗鼓這樣:http://sqlfiddle.com/#!9/caeb1e/5

有一個非常好的圖片如何加入實際工作可以在這裏找到:http://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins

SQL Joins

+0

你能否描述我在用戶方面有什麼問題?我知道不同的SQL連接,所以你的圖不能幫助我。我想在內部理解事情的工作方式! – python

+0

尋找將用於「選擇」和「連接」的算法。你能說一下嗎? – python

+0

請問您可以添加一個參考資料,從這張圖上可以得知。另外,我認爲他在OP中的僞代碼實際上比圖表更好地解釋了輸出。 –

0

是你的理解是正確的,如果你只在談論一個聯接不上其它連接如:內,外像SQL

+0

檢查我的更新! – python

+0

是的,這是正確的。 –

1

在你的第二個查詢中,你不確定你想要做什麼,因爲語法是錯誤的;但如果我猜測,看起來你的意圖是加入用戶U1與在追隨者F和用戶U2之間的(隱式)聯接的子查詢。

如果我的猜測是正確的,查詢將正確看上去就像這樣:

SELECT U1.uid, U1.uname 
FROM User U1 JOIN 
    (SELECT U2.uid 
    FROM Followers F,User U2 
    WHERE F.followerid = U2.uiddate AND U2.ucity = 'D') T 
WHERE u1.uid = T.uid 

這是不是寫查詢的「最佳實踐」的方式是(你應該用明確連接,就沒有必要對於一個子查詢,但你可以只加入三次,依此類推) 但我這樣寫了它,以保持它最接近你的原始查詢。

如果我的猜測是正確的,那麼你的僞代碼會更喜歡:

for u2 in [User 2 where condition]: 
     for f in [Follows]: 
      if f.uid == u2.uid 
      SELECT uid AS T 
       for u1 in [User 1]: 
       if u1.uid == T.uid: 
        print <> 

但是,它不是一個完全解釋的解釋,因爲一個關鍵是理解SQL是想更多的「設置」的數據被過濾,而不是按順序選擇數據對象,因爲SQL基於一組數據執行操作,而這些操作可能不適用。 因此,以上幾個步驟將一次執行,而不是順序執行。但除此之外,您應該看看上面的Yuri Tkachenko給出的答案,以及如何查看連接 - 然後在編寫正確的連接時內部將獲得第二。