LINQ查询分组和排名

时间:2011-01-23 17:13:54

标签: c# linq

我有一个名为预测的SQL表,数据如下

Week    Player     Points
201101  Mark       7
201101  Mark       7
201101  Pete       7
201101  Pete       3
201101  Mark       5
201102  Mark       2
201102  Mark       3
201102  Pete       7
201102  Pete       5
201102  Mark       5
201103  Mark       7
201103  Mark       7
201103  Pete       7
201103  Pete       3
201103  Mark       5

表格中的每一行代表一场足球比赛,因此每周有几场

我需要的结果是

Player    Count of Weekly wins
Mark      2
Pete      1

因此,马克在2011011和201103赛季得分最高,皮特在201102赛季得分最高

获得每位玩家每周的总分数很容易。但我无法弄清楚如何从每周小组中取得最高成绩并获得我需要的结果。

我在sql查询中使用RANK函数,然后选择排名为1的所有玩家。这很好,因为如果两个玩家一周有相同的分数,他们都会被正确计算。但我想要一个LINQ版本,因为它很酷,适合我对网站的改造!

任何帮助都将不胜感激。

好的,我已经达到了这个目的,即每个星期每个玩家的数据总结。我现在需要做的是选择每周最上面的条目并将其计入玩家

(from p in FootballPredictions
        where p.FootballMatches.WeekNum <= 201101 && p.Points != null
        group p by new { p.FootballMatches.WeekNum, p.Player } into g
        orderby g.Key.WeekNum, g.Sum(p => p.Points) descending
        select new
        {
            WeekNum = g.Key.WeekNum,
            Player = g.Key.Player,
            Points = g.Sum(p => p.Points),
        })

给予

WeekNum Player           Points 
201033  ranteld           26           <--- 1 point
201033  nicolap           25
201033  Mark              25
201033  1969 cup winners  25
201033  footysi           24
201033  Brendan           22
201033  monty             22
201033  Sandra Phillips   21
201033  SPB               20
201033  John Poulton      20
201033  RobBrown          19
201033  Steve Gardner     17
201033  Nick              16
201033  MikeSpeke         15
201034  Sandra Phillips   32           <--- 1 point
201034  Steve Gardner     27
201034  ranteld           25
201034  John Poulton      23
201034  footysi           23
201034  Mark              17
201034  nicolap           13
201034  Brendan           13
201035  Brendan           34           <--- 1 point
201035  Sandra Phillips   34           <--- 1 point
201035  nicolap           31
201035  1969 cup winners  25
201035  MikeSpeke         24
201035  Steve Gardner     22
201035  Mark              20
201035  ranteld           20
201035  Football Freddie  16

所以这张表的真正答案是

Player             Wins
Sandra Philips      2
Brendan             1
ranteld             1

希望澄清

5 个答案:

答案 0 :(得分:3)

看到您的查询似乎与数据不对应,这有点令人困惑。相反,这将仅基于数据。查询应生成有效的SQL,因此您不必使用LINQ to Objects。您只需稍加修改即可将其调整到您的桌面。

var query = from pred in Predictions
            group pred.Points by pred.WeekNum into week
            join pred in Predictions
                on new { WeekNum = week.Key, Points = week.Max() }
                equals new { pred.WeekNum, pred.Points }
            group 1 by pred.Player into player
            let Wins = player.Count()
            orderby Wins descending, player.Key
            select new
            {
                Player = player.Key,
                Wins,
            };

答案 1 :(得分:2)

尝试:

p.Points.Any()

而不是:

p.Points != null

答案 2 :(得分:0)

此代码似乎是您所需要的:

    var result = this.DataList
            .GroupBy(data => data.Week)
            .Select(data=>
            {
                return data.GroupBy(item => item.Name)
                    .Select(item => new { Name = item.Key, SumPoints = item.Sum(v => v.Points) })
                    .OrderBy(item => item.SumPoints)
                    .FirstOrDefault();
            })
            .GroupBy(_=>_.Name)
            .ToDictionary(_=>_.Key, _=>_.Count());

答案 3 :(得分:0)

我很长很长时间

var weeklyTopScore = from eachMatch in FootballPredictions
                     group eachMatch by eachMatch.week
                     into weekly
                     select new {week = weekly.Key, topScore = weekly.Max(match => match.points)};

var playerWins = from eachResult in weeklyTopScore
                 join entry in FootballPredictions
                 on eachResult.week equals entry.week
                 where eachResult.topScore == entry.points
                 group entry by entry.player
                 into winner
                 select new { player = winner.Key, wins = winner.Count() };

var result = from entry in playerWins
             group entry by entry.wins
             into summary
             select new { player = summary.Select(data => data.player).Aggregate((cur, nex) => cur + ", " + nex), wins = summary.Key};

答案 4 :(得分:0)

只需将数据表传递给以下函数(请注意代码在c#中) // dt应包含列点但不包含排名列

 public static DataTable GetRankedDatatable(DataTable dt)
            {
                var rankedDt = (from row in dt.AsEnumerable()
                                orderby row.Field<string>("points")
                                select row).CopyToDataTable();
                rankedDt.Columns.Add("rank");
                int rank = 0;
                for (int i = 0; i < rankedDt.Rows.Count - 1; i++)
                {
                    rankedDt.Rows[i]["rank"] = rank;
                    if (rankedDt.Rows[i]["points"].ToString() != rankedDt.Rows[i + 1]["points"].ToString())
                    {
                        rank++;
                    }
                }
                rankedDt.Rows[rankedDt.Rows.Count - 1]["rank"] = rank;
                return rankedDt;
            }