将SQL Rank()转换为LINQ,或替代
我有下面的SQL语句,可以按预期/预期工作。 但是我想将它翻译成LINQ语句(Lambda ??),以便它适合我的其余DAL。 但是我无法弄清楚如何在LINQ中模拟Rank()。
我在这里发布它的原因,可能是错误的,是看看是否有人可以替换Rank()
语句,以便我可以切换它。 或者,如果有一种方法可以在LINQ中表示Rank()
,也可以理解。
USE CMO SELECT vp.[PersonID] AS [PersonId] ,ce.[EnrollmentID] ,vp.[FirstName] ,vp.[LastName] ,ce.[EnrollmentDate] ,ce.[DisenrollmentDate] ,wh.WorkerCategory FROM [dbo].[vwPersonInfo] AS vp INNER JOIN ( [dbo].[tblCMOEnrollment] AS ce LEFT OUTER JOIN ( SELECT * ,RANK()OVER(PARTITION BY EnrollmentID ORDER BY CASE WHEN EndDate IS NULL THEN 1 ELSE 2 END, EndDate DESC, StartDate DESC) AS whrank FROM [dbo].[tblWorkerHistory] WHERE WorkerCategory = 2 ) AS wh ON ce.[EnrollmentID] = wh.[EnrollmentID] AND wh.whrank = 1 ) ON vp.[PersonID] = ce.[ClientID] WHERE (vp.LastName NOT IN ('Client','Orientation','Real','Training','Matrix','Second','Not')) AND ( (wh.[EndDate] = GetDate()) )
这是一个示例,展示了如何在Linq中模拟Rank():
var q = from s in class.student orderby s.Age descending select new { Name = s.name, Rank = (from o in class.student where o.mark > s.mark select o).Count() + 1 };
LINQ内置了级别function,但查询语法中没有。 当使用方法语法时,大多数linq函数有两个版本 – 正常的和一个提供的等级。
一个简单的示例,仅选择所有其他学生,然后将结果序列中的索引添加到结果中:
var q = class.student.OrderBy(s => s.studentId).Where((s, i) => i % 2 == 0) .Select((s,i) => new { Name = s.Name, Rank = i }
如果您想模拟排名,那么您可以使用以下linq查询。
var q = (from s in class.student select new { Name = s.Name, Rank = (from o in class.student where o.Mark > s.Mark && o.studentId == s.studentId select o.Mark).Distinct().Count() + 1 }).ToList();
您可以通过以下方式使用订单:
var q = (from s in class.student orderby s.studentId select new { Name = s.Name, Rank = (from o in class.student where o.Mark > s.Mark && o.studentId == s.studentId select o.Mark).Distinct().Count() + 1 }).ToList();
但是在这个查询中,顺序并不重要。
基于@Totero的答案,但有一个lamda实现。 得分越高=等级越高。
var rankedData = data.Select(s => new{ Ranking = data.Count(x => x.Value > s.Value)+1, Name = s.Key, Score = s.Value});
对于此输入:
{ 100, 100, 98, 97, 97, 97, 91, 50 }
你会得到这个输出:
- 分数:排名
- 100:1
- 100:1
- 98:3
- 97:4
- 97:4
- 97:4
- 91:6
- 50:7