您的位置:首页 > 数据库

【C#】31. LINQ 与 SQL 的抗争! 小议 NTILE() 和 自写的拓展函数

2016-01-31 23:02 447 查看
最近在准备期货考试和计算机数据库三级,应该说是两门我一定要拿下的考试。

昨天正好看到介绍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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: