2013-10-21 29 views
5

在数据库(SQL Server)的,比方说,一个列值,如:如何从整数列表中计算排名?

Col1 
==== 
10 
5 
15 
20 
5 
10 
2 

这就像整型数据的列表。

排名应该是:

Col1 Rank 
==== ==== 
20 1 
15 2 
10 3 
10 3 
5  4 
5  4 
2  5 

我在下面的方式都试过:

1) First sort the list of data in descending order of "Col1" value 
2) Find the index of a particular record using FindIndex() method. 
3) Then Rank = Index + 1 

但是,如果数据是唯一的它只会工作。当索引返回0, 1, 2, 3, 4, 5, 6时,如果同一个“Col1”值出现在多行中,它将失败。

如何使用C#LINQ来计算列表包含不明显的数据(大多数情况下!)的等级?

+0

什么,如果第一,然后采取不同的值做了上面的场景... –

回答

5

为什么不在数据库中做到这一点?

SELECT [Col1], DENSE_RANK() OVER (ORDER BY Col1 DESC) AS [Rank] 
FROM Table 

但是如果你必须在C#中做

var data = new List<int>(); 
var rankings = data.OrderByDescending(x => x) 
        .GroupBy(x => x) 
        .SelectMany((g, i) => 
         g.Select(e => new { Col1 = e, Rank = i + 1 })) 
        .ToList(); 
+2

这是不对的。应该使用'dense_rank()'。 C#代码也是错误的。 – GSerg

+0

我相信这个问题说等级= index + 1 – gleng

+0

@GSerg我从来没有听说过这个功能,谢谢! – Romoku

1

如果你会做它在数据库中(可以通过运行一个查询或通过从视图中选择),查询/视图应该是因此:

SELECT [Col1], DENSE_RANK() OVER (ORDER BY Col1 DESC) AS [Rank] 
FROM OriginalTable 

这是容易得多,比C#或必须首先检索数据,然后后处理任何其他语言做这件事更快。

+0

If问题是“我该如何使用C#LINQ来做这件事?”,那么你的答案如何适当呢?另外:你怎么知道你的SQL解决方案更快?你运行测试与C#解决方案吗?如果是这样,请发布你的号码。 –

+1

SQL Server可为您执行的任何计算运行速度都比您首次获取数据时快,然后对该数据执行计算。这是因为SQL Server可以优化它提取数据的方式,并且其计算引擎针对速度进行了优化。这不仅仅是一个明显的例子,还包括在VIEW中计算列的情况。是的,很多年前我都运行过测试,而且我们甚至在SQL Server中进行了非常复杂的计算。 –

+0

答案如何?因为OP可能不知道在SQL Server中进行计算是一个可行的选择。 –

1

在C#:

var data = new List<int> { 10, 12, 7, 8, 7, 6, 3, 3, 4 }; 
var rankings = data.OrderByDescending(x => x).GroupBy(x => x) 
        .SelectMany((g, i) => 
         g.Select(e => new { Col1 = e, Rank = i + 1 })) 
        .ToList();