在SQL Server 中合理的使用 LEFT OUTER JOIN 進行開發
比如我們想對某人的消費項目進行匯總,對應以下兩個表:Theme 與 ThemeDetail
Theme 的記錄為:
ThemeID(int)????ThemeName(varchar[10])
????????1????????????????????????就餐
????????2????????????????????????出差
????????3????????????????????????乘車
????????4????????????????????????其它
ThemeDetail 的記錄為:
DetailID(int)????ThemeID(int)????Price(money)
??? ???1????????????????????1?????????????????12.5
? ?????2????????????????????1????????????????????5
? ?????3????????????????????1????????????????????6
? ?????4????????????????????2???????????????????11
? ???? 5????????????????????2???????????????????17
? ???? 6????????????????????3????????????????????8
其中 Theme 中的 ThemeID 與 ThemeDetail 中的 ThemeID 是一對多的關系,對 ThemeDetail 表的理解如下:“就餐”費用為 12.5 + 5 + 6 = 23.5 元,“出差”費用為 11 + 17 = 28 元,“乘車”費用為 8 = 8 元,“其它”費用不存在,視為 0 處理,對應的 SQL 語句可以這樣表示:
SELECT TOP 100 PERCENT dbo.Theme.ThemeName, ISNULL(SUM(dbo.ThemeDetail.Price), 0)
????? AS TotalPrice
FROM dbo.Theme INNERJOIN
????? dbo.ThemeDetail ON dbo.Theme.ThemeID = dbo.ThemeDetail.ThemeID
GROUP BY dbo.Theme.ThemeName, dbo.Theme.ThemeID
ORDER BY dbo.Theme.ThemeID
執行結果如下:
ThemeName????TotalPrice
????就餐????????????? 23.5
????出差?????????????? 28
????乘車??????????????? 8
對于消費記錄不存的記錄如果就這樣不顯示它的話,使用內聯的方法就可以滿足要求了,但是我們現在需要對 Theme 中的每一項均做統計,也包括“其它”項,于是我們應該采用另一種方法來實現,這就是左外聯的方法,相應的 SQL 語句可以這樣表示:
SELECT TOP 100 PERCENT dbo.Theme.ThemeName, ISNULL(SUM(dbo.ThemeDetail.Price), 0)
????? AS TotalPrice
FROM dbo.Theme LEFTOUTER JOIN
????? dbo.ThemeDetail ON dbo.Theme.ThemeID = dbo.ThemeDetail.ThemeID
GROUP BY dbo.Theme.ThemeName, dbo.Theme.ThemeID
ORDER BY dbo.Theme.ThemeID
執行結果如下:
ThemeName????TotalPrice
????就餐????????????? 23.5
????出差?????????????? 28
????乘車??????????????? 8
????其它????????????????0
這樣是不是就滿足了我們的要求呢!
我測試了 10 萬條記錄后發現速度并非兄弟所說的那樣,測試代碼如下
*/
declare @StartTime datetime
set @StartTime = getdate()
SELECT TOP 100 PERCENT ThemeName, ISNULL(SUM(Price), 0) AS TotalPrice
FROM Theme LEFT OUTER JOIN ThemeDetail ON Theme.ThemeID = ThemeDetail.ThemeID
GROUP BY ThemeName, Theme.ThemeID
ORDER BY Theme.ThemeID
select datediff(millisecond,@StartTime,getdate())
set @StartTime = getdate()
SELECT TOP 100 PERCENT ThemeName, ISNULL((SELECT SUM(ThemeDetail.Price)
FROM ThemeDetail
WHERE ThemeDetail.ThemeID = Theme.ThemeID), 0) AS TotalPrice
FROM Theme
GROUP BY ThemeName, ThemeID
ORDER BY ThemeID
select datediff(millisecond,@StartTime,getdate())
/* 測試結果如下,精確到毫秒,最后是平均值 */
次數 時間 時間
----------------------
1 93 110
2 93 93
3 93 110
4 93 93
5 93 110
6 93 110
7 93 93
8 93 93
9 93 93
10 93 126
11 110 110
12 93 126
13 96 123
14 93 126
15 93 110
16 93 123
17 106 96
18 93 93
19 106 96
20 93 93
----------------------
95.3 106.35