使用LINQ排名和相同点的排行榜排名

时间:2015-02-03 06:33:55

标签: c# sql linq

我的数据库中有以下表格:
用户表
用户名
名称

我打算做什么:

| Rank |  Name |  Point  |
| 344  | UserA |  2000   |
| 345  | UserB |  1500   |
| 345  | UserC |  1500   |
| 347  | UserD |  1200   |
| 348  | UserE |  1000   |
| 349  | UserF |  1000   | <-- targeted user
| 350  | UserG |  900    |
| 350  | UserH |  800    |
| 352  | UserI |  700    |
| 353  | UserJ |  600    |

我尝试了什么:

int point = 1000;
var top6 = db.User.Where(p => p.Point >= point).OrderBy(p => p.Point).Take(6);
var bottom4 = db.User.Where(p => p.Point < point).OrderByDescending(p => p.Point).Take(4);

var leaderboard = top6.Union(bottom4).OrderByDescending(p => p.Point);

目前的结果是什么?

&#13;
&#13;
|  Name |  Point  |
| UserA |  2000   |
| UserB |  1500   |
| UserC |  1500   |
| UserD |  1200   |
| UserE |  1000   |
| UserF |  1000   | <-- targeted user
| UserG |  900    |
| UserH |  800    |
| UserI |  700    |
| UserJ |  600    |
&#13;
&#13;
&#13;

还有什么未解决的?

  • 如图所示分配全球排名
  • 排名中存在平局的条件

我有什么问题? - 不知道如何为用户分配全局排名。 - 不知道如何解决排名条件。当平局时,等级应该相同

2 个答案:

答案 0 :(得分:1)

//编辑: Linqpad Instant Share重现它: http://share.linqpad.net/urtpc9.linq

我对shree.pat18略有不同。我没有生成列表并将其压缩,而是使用重载的Select()方法在对结果进行分组后生成索引,以处理Tie的点数。

来自LinqPad的代码:

void Main()
{
    var players = new List<Player>()
    {
        new Player() {Name ="UserA", Points=2500},
        new Player() {Name ="UserB", Points=2400},
        new Player() {Name ="UserC", Points=2300},
        new Player() {Name ="UserD", Points=2200},
        new Player() {Name ="UserE", Points=2100},
        new Player() {Name ="UserF", Points=2000},
        new Player() {Name ="UserG", Points=1900},
        new Player() {Name ="UserH", Points=1800},
        new Player() {Name ="UserI", Points=1800},
        new Player() {Name ="UserJ", Points=1700},
        new Player() {Name ="UserK", Points=1600},
        new Player() {Name ="UserL", Points=1500},
        new Player() {Name ="UserN", Points=1300},
        new Player() {Name ="UserM", Points=1300},
    };

    var TargetPoints = 1000;

    var RankedPlayers =  players.OrderByDescending(p => p.Points)
                                .GroupBy (p => p.Points)
                                .Select ((grp, i) => new {
                                    Rank = i,
                                    Players = grp.OrderByDescending (g => g.Name)
                                })
                                .Dump();



}
public class Player
{
    public string Name { get; set; }
    public int Points { get; set; }
}

LinqPad中的输出:

enter image description here

答案 1 :(得分:0)

试试这个:

   int point = 1000;          
   var ranks = Enumerable.Range(1,db.User.Count);
   var result = db.User.OrderByDescending(x => x.points).ThenBy(x => x.Name).Zip(ranks, (x,y) => new {x.Name, x.Point, rank = y});
   var top6= result.Where(x => x.Point>= point).OrderBy(x => x.Point).Take(6);            
   var bottom4 = result.Where(x => x.Point< point).OrderByDescending(x => x.Point).Take(4);
   var leaderboard = top6.Union(bottom4).OrderByDescending(x => x.Point).ThenBy(x => x.Name);

Demo

首先生成一个有序列表,我们将其用作全局排名。使用适当排序的用户列表将其压缩。压缩步骤的输出是包含排名字段的匿名对象的集合。然后,只需使用返回的集合和您的逻辑来获得顶部,底部和组合结果。