比如我們想對某人的消費(fèi)項(xiàng)目進(jìn)行匯總,對應(yīng)以下兩個(gè)表: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 是一對多的關(guān)系,對 ThemeDetail 表的理解如下:“就餐”費(fèi)用為 12.5 + 5 + 6 = 23.5 元,“出差”費(fèi)用為 11 + 17 = 28 元,“乘車”費(fèi)用為 8 = 8 元,“其它”費(fèi)用不存在,視為 0 處理,對應(yīng)的 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
執(zhí)行結(jié)果如下:
ThemeName????TotalPrice
????就餐????????????? 23.5
????出差?????????????? 28
????乘車??????????????? 8
對于消費(fèi)記錄不存的記錄如果就這樣不顯示它的話,使用內(nèi)聯(lián)的方法就可以滿足要求了,但是我們現(xiàn)在需要對 Theme 中的每一項(xiàng)均做統(tǒng)計(jì),也包括“其它”項(xiàng),于是我們應(yīng)該采用另一種方法來實(shí)現(xiàn),這就是左外聯(lián)的方法,相應(yīng)的 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
執(zhí)行結(jié)果如下:
ThemeName????TotalPrice
????就餐????????????? 23.5
????出差?????????????? 28
????乘車??????????????? 8
????其它????????????????0
這樣是不是就滿足了我們的要求呢!
/*
我測試了 10 萬條記錄后發(fā)現(xiàn)速度并非兄弟所說的那樣,測試代碼如下
*/
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())
/* 測試結(jié)果如下,精確到毫秒,最后是平均值 */
次數(shù) 時(shí)間 時(shí)間
----------------------
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