平常公司都會有匯出報表的功能,通常這類型資料都可以在SQL中完成。
EX:該月業績最好的業務員
1月 小王 (30筆訂單)
2月 小陳 (40筆訂單)
3月 小林 (20筆訂單)
類似這樣的資料在SQL中只需要GROUP + MAX就可以完成,使用LINQ時候也是GROUP + COUNT就可以完成。
但如果情境變成NOSQL,沒有GROUP這種函數,並且要呈現的資料為
「當月業績最好的人,並算出 該月 的 每日業績總額」
就會變成依據月份來算每日Total,此時使用SUM也不是、MAX也不是,往往就是跑for迴圈,給予初始值,月份結束時候重新計算,其實可以不用這麼麻煩,可以透過Aggregate()來幫我們處理。
參考連結
奎Kuei的LINQ - Aggregate()
91大的[.NET]快快樂樂學LINQ系列-Aggregate() 簡介
這段是在介紹Aggregate中,三個參數個別的用途
1.seed:初始值
2.func:呼叫的函式(seed, item)
這邊的seed是來自於上一筆資料的seed,如果不懂得等等看範例就知道了。
item就是foreach的當前資料
3.resultSelector:依據seed + func處理後,取得的最終結果
這段在介紹Aggregate可以使用的多載方法,建議開個主控台應用程式跟著步驟1、2、3做一次會比較容易理解
1.Aggregate(func):不給初始值
List<string> numbers = new List<string> { "6", "2", "8", "3" };
string tmp = numbers.Aggregate(
func: (seed, item) => seed + "*" + item
);
Console.WriteLine(tmp);
第一次 null + "*" + "6" = "6"
註※這邊理應會變成 "*" + 6,推測是因為seed沒給預設值,所以第一次並未執行,並把6的值傳給seed,如果理解有誤還請告知。
第二次 "6" + "*" + "2" = "6*2"
第三次 "6*2" + "*" + "8" = "6*2*8"
所以第四次理應變成"6*2*8*3",執行看看結果吧!
2.Aggregate(seed, func)
List<string> numbers2 = new List<string> { "6", "2", "8", "3" };
string tmp2 = numbers2.Aggregate(
seed: "1", func: (seed, item) => seed + "*" + item
);
Console.WriteLine(tmp2);
這邊由於有初始值,所以第一次的運算式會是
"1" + "*" + "6"
後續的執行方式參照方法1
所以印出來的結果會是"1*6*2*8*3"
3.Aggregate(seed, func, resultSelector)
List<int> numbers3 = new List<int> { 6, 2, 8, 3 };
double tmp3 = numbers3.Aggregate(
seed: 0,
func: (result, item) => result + item,
resultSelector: result => (double)result / numbers.Count);
Console.WriteLine(tmp3);
根據這次的資料處理,得到的最後結果為19。將其轉型為double,並除上COUNT,得到的結果為4.75
依據這個上面所了解的,再加以變形就可以做到SUM、AVG、MAX、MIN的效果了,也就是說每個月業績最高(GROUP)的每日業績總額(Aggregate)就可以做出來了。
SUM:
List<int> numbers4 = new List<int> { 6, 2, 8, 3 };
double tmp4 = numbers4.Aggregate(
seed: 0,
func: (result, item) => result + item);
Console.WriteLine(tmp4);
AVG(範例3):
List<int> numbers3 = new List<int> { 6, 2, 8, 3 };
double tmp3 = numbers3.Aggregate(
seed: 0,
func: (result, item) => result + item,
resultSelector: result => (double)result / numbers.Count);
MAX:
List<int> numbers5 = new List<int> { 6, 2, 8, 3 };
int tmp5 = numbers5.Aggregate(
seed: 0,
// 透過三元運算子做大小的比較,來決定要留下哪個數值
func: (result, item) => result > item ? result: item);
Console.WriteLine(tmp5);
MIN:
List<int> numbers6 = new List<int> { 6, 2, 8, 3 };
int tmp6 = numbers6.Aggregate(
// 透過三元運算子做大小的比較,來決定要留下哪個數值
func: (result, item) => result < item ? result: item);
Console.WriteLine(tmp6);
感謝專心寫好程式 奎大耐心指導,今日滿載而歸,謝謝!
歡迎您的加入,讓這個社群更加美好!