【C#】31. LINQ 與 SQL 的抗爭! 小議 NTILE() 和 自寫的拓展函數

最近在準備期貨考試和計算機數據庫三級,應該說是兩門我一定要拿下的考試。

昨天正好看到介紹SQL中關於OVER和Partition by 以及 NTILE 等的語法,用SQL着實非常方便。但是作爲一名對 C# 有感情的人,我決定用Linq實現一把。

其實也就兩個例題,原始數據表是 MyOrderDetail:


【例22】 將該表數據按訂購數量降序排列,並將該表數據劃分到4個組中。

SQL:

SELECT OrderID, ProductID, OrderQty, 
	NTILE(4) OVER (ORDER BY OrderQty DESC) AS FourGroups
FROM OrderDetail


教程上的結果是


以下是我的LINQ方法,裏面有幾個我自己寫的拓展方法,先上代碼:

var q = MyOrderDetailDT.AsEnumerable().OrderByDescending(dr => dr.Field<int>("OrderQty"))
                .Zip(DRCount.DistToArray(4),(dr,l2)=>new {OrderID = dr[0],ProductID=dr[1],OrderQty = dr[2], FourGroups = l2})
                .ToDataTable();
結果如下:




【例23】 修改例22的查詢要求。將每個訂單中的數據按訂購數量降序排序,並將每個訂單的數據劃分到3個組中。

SQL:

SELECT Order, ProductID, OrderQty,
     NTILE(3)
OVER (PARTITION BY OrderID ORDER BY OrderQty DESC) AS ThreeGroups
FROM OrderDetail
教程上的結果是:



我的Linq代碼:

var q2 = MyOrderDetailDT.AsEnumerable().GroupBy(dr => dr["OrderID"]).Select(grp => grp)
                .SelectMany(grp
                => grp.OrderByDescending(dr2 => dr2["OrderQty"]).Zip(grp.Count().DistToArray(3),
                (dr2, l2) =>
                new { OrderID = dr2[0], ProductID = dr2[1], OrderQty = dr2[2], ThreeGroups = l2 }))
                .ToDataTable();
結果是:


好了,結果是一致的。這裏就講兩點吧!一、SQL使用的好的確很方便;二、SQL 中的NTILE函數,他的賦值方式是分組循環累加,10分爲4組,因爲不能整除,所以一次遍歷1,2,3,4,他們分別加1,再重複一次,又分別加1,最後一次遍歷,由於只遍歷到1和2,所以他們兩分別加1,而3和4就停留在 2。

發佈了68 篇原創文章 · 獲贊 20 · 訪問量 23萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章