我想知道是否有人可以幫助提高我對SQL中JOIN的理解。 [如果問題很重要,我特意考慮MS SQL Server。]瞭解JOIN在涉及3個或更多表時如何工作。 [SQL]
取3個表A,B [與某些A.AId相關的A],以及C [B與某個B有關的C .BId]
如果我編寫一個查詢如
SELECT *
FROM A JOIN B
ON A.AId = B.AId
都好 - 我是甜中帶是如何工作的。
當表C(或其他d,E,......被添加),會發生什麼
的情況
SELECT *
FROM A JOIN B
ON A.AId = B.AId
JOIN C ON C.BId = B.BId
什麼是C加入到? - 它是B表(和B表中的值嗎?) 或者它是C表加入的A + B連接的結果的某個其他臨時結果集?
[言下之意是不是在B表中的所有值必然是在基於用於連接條件的臨時結果集A + B,B]
的具體(和相當人爲的)例子爲什麼我問的是因爲我想了解的行爲,我在下面看到:
Tables
Account (AccountId, AccountBalanceDate, OpeningBalanceId, ClosingBalanceId)
Balance (BalanceId)
BalanceToken (BalanceId, TokenAmount)
Where:
Account->Opening, and Closing Balances are NULLABLE
(may have opening balance, closing balance, or none)
Balance->BalanceToken is 1:m - a balance could consist of many tokens
概念,截止日期的平衡,將是明天的期初餘額
如果我試圖找到所有的開幕和期末餘額爲帳戶
我可能會做這樣的事情
SELECT AccountId
, AccountBalanceDate
, Sum (openingBalanceAmounts.TokenAmount) AS OpeningBalance
, Sum (closingBalanceAmounts.TokenAmount) AS ClosingBalance
FROM Account A
LEFT JOIN BALANCE OpeningBal
ON A.OpeningBalanceId = OpeningBal.BalanceId
LEFT JOIN BALANCE ClosingBal
ON A.ClosingBalanceId = ClosingBal.BalanceId
LEFT JOIN BalanceToken openingBalanceAmounts
ON openingBalanceAmounts.BalanceId = OpeningBal.BalanceId
LEFT JOIN BalanceToken closingBalanceAmounts
ON closingBalanceAmounts.BalanceId = ClosingBal.BalanceId
GROUP BY AccountId, AccountBalanceDate
事情工作,我所期望的,直到最後JOIN帶來期末餘額令牌 - 在我結束了在結果重複。
[我可以用DISTINCT解決 - 但我想知道爲什麼發生了什麼正在發生的事情]
有人告訴我這個問題是因爲平衡之間的關係,並BalanceToken是1:M - 和當我引入最後一個JOIN時,我得到了重複,因爲第三個JOIN已經多次將BalanceIds引入(我假設)臨時結果集中。
我知道,例如表不符合良好的DB設計
道歉的文章,感謝您的任何elightenment :)響應
編輯馬克·
概念爲質疑賬戶裏不應該有重複賬戶的BalanceToken(根據AccountingDate) - 我認爲問題的關鍵是因爲1賬戶/會計賬戶餘額結餘是賬戶餘額在第二天 - 所以當自我加入餘額,BalanceToken多次到獲得期初和期末餘額我認爲B alances(BalanceId)被多次納入'結果組合'。如果有助於澄清第二個例子,可以將其視爲每日對帳 - 因此,剩下的加入 - 可能沒有爲給定的賬戶/會計日期組合計算開放(和/或)結賬餘額。
+1詳細的問題和自己的推理。 – PatrikAkerstrand 2009-07-05 08:30:26
小小的OT,但值得一提:http://www.codeproject.com/KB/database/Visual_SQL_Joins.aspx – 2009-07-05 09:13:28