C# 分組查詢
分組查詢(group query)把數(shù)據(jù)分解為組,允許按組來(lái)排序、計(jì)算聚合值以及進(jìn)行比較。這常常是商務(wù)環(huán)境中最有趣的查詢(它驅(qū)動(dòng)了決策系統(tǒng))。例如,要按照國(guó)家或區(qū)域比較銷(xiāo)售量,確定在哪里開(kāi)新店或雇用更多員工,如下例所示。
試一試 分組查詢:BeginningCSharp7—22_10_J3roupQuery\Program.cs
按照下面的步驟在Visual Studio 2017中創(chuàng)建示例:
(1)在 C:\BeginningCSharp7\Chapter22自錄中創(chuàng)建一個(gè)新的控M臺(tái)應(yīng)用程序 BeginnitigCSliarp7_22_lO_GroupQuery。
(2)如 BeginningCSharp7_22_8_SelectDistinctQuery 示例所示,創(chuàng)建 Customer 類并初始化 customers 列表(List<Customer> customers),這些代碼與前面示例中的代碼完全相同。
(3)在Main()方法的customers列表初始化后,輸入如下所示的兩個(gè)査詢:
var queryResults =
from c in customers
group c by c.Region into cg
select new { TotalSales = cg.Sum(c => c.Sales), Region = eg.Key }
;
var orderedResults =
from eg in queryResults
orderby eg.TotalSales descending
select eg
;
(4)在MainO方法中,添加下面的輸出語(yǔ)句和foreach處理循環(huán):
WriteLine(MTotal\t: By\nSales\t: RegionNn-----\t ------");
foreach (var item in orderedResults)
{
WriteLine($"{item.TotalSales}\t: {item.Region}");
}
(5)結(jié)果處理循環(huán)和MainO方法中的其余代碼與前面例子中的相同。編譯并執(zhí)行程序,下面是分組結(jié)果:
Total : By
Sales : Region
----- -----
52997 : Asia
16999 : North America
12444 : Europe
8558 : South America
7000 : Africa
示例說(shuō)明
Customer類和customers列表的初始化與前面例子中的相同。
分組查詢中的數(shù)據(jù)通過(guò)一個(gè)鍵(key)字段來(lái)分組,每個(gè)組中的所有成員都共享這個(gè)字段值。在這個(gè)例子中,鍵字段是Region:
group c by c.Region
要計(jì)算每個(gè)組的總和,應(yīng)生成一個(gè)新的結(jié)果集eg:
group c by c.Region into eg
在select子句中,投影了一個(gè)新的匿名類型,其屬性是總銷(xiāo)售量(通過(guò)引用eg結(jié)果集來(lái)計(jì)算)和組的鍵值, 后者是用特殊的組Key來(lái)引用的:
select new { TotalSales = eg.Sum(c => c.Sales), Region = eg.Key }
組的結(jié)果集實(shí)現(xiàn)了UNQ接口 IGrouping,它支持Key屬性。我們總以某種方式引用Key屬性,來(lái)處理分組結(jié)果,因?yàn)樵搶傩员硎緞?chuàng)建數(shù)據(jù)中的每個(gè)組時(shí)使用的條件。
要按TotalSales字段對(duì)結(jié)果降序排序,以便查看哪個(gè)區(qū)域的銷(xiāo)售置最高、哪個(gè)區(qū)域的銷(xiāo)售量次高等,需要?jiǎng)?chuàng)建第二個(gè)査詢,對(duì)分組查詢的結(jié)果排序:
var orderedResults =
from eg in queryResults
orderby cg.TotalSales descending
select eg
;
第二個(gè)査詢是一個(gè)標(biāo)準(zhǔn)的select査詢,帶一個(gè)ordeiby子句,與前面示例中的相同。但它沒(méi)有使用任何UNQ分組功能,只是數(shù)據(jù)源來(lái)自于前面的分組査詢。
接著輸出結(jié)果,用一些格式化代碼顯示帶有列標(biāo)題的數(shù)據(jù),在總銷(xiāo)售量與組名之間顯示了分隔符:
WriteLine("Total\t: By\nSales\t: Region\n---\t ---");
foreach (var item in orderedResults)
{
WriteLine($"{item. TotaISales}\t: {item. Region}");
};
可以用更復(fù)雜的方式進(jìn)行格式化,指定字段寬度,總銷(xiāo)售量右對(duì)齊,但這只是一個(gè)例子,不需要這么多格式,能看清數(shù)據(jù),理解代碼做了些什么就足夠了。
點(diǎn)擊加載更多評(píng)論>>