使用LINQ获得几个SUM的MAX

时间:2014-05-22 19:36:04

标签: c# sql linq

我有一个名为UserActivity的表,它有ActivityId和Points列。条目不是唯一的,因此有许多行具有相同的ActivityId。我想要的是总结每个活动的所有积分,然后返回具有最多积分的活动的ActivityId和Points。所以,在SQL中,像这样(未经测试):

SELECT ActivityPoints.ActivityId
FROM (
    SELECT ActivityId, SUM(Points) AS TotalPoints
    FROM db.UserActivity
    GROUP BY ActivityId
) AS ActivityPoints
HAVING ActivityPoints.TotalPoints = MAX(ActivityPoints.TotalPoints)

我如何在LINQ中实现这一目标?我是新手,所以我不确定我在做什么。


所有伟大的答案,每个人!我最后从他们每个人那里学到了一点点。感谢。

3 个答案:

答案 0 :(得分:1)

您可以按活动组分组,将每项活动的积分相加,按降序排序,并取第一个结果

db.UserActivity
.GroupBy(m => m.ActivityId)
.Select(m => new {
   activityId = m.Key,
   sumPoints = m.Sum(x => x.Points)
})
.OrderByDescending(x => x.sumPoints)
.First()
.activityId;

可以简化为

db.UserActivity
    .GroupBy(m => m.ActivityId)
    .OrderByDescending(x => x.Sum(s => s.Points))
    .First()
    .Key;

答案 1 :(得分:1)

您是否尝试创建自己的StackOverflow? : - )

IEnumerable<UserActivity> UserActivities = LoadUserActivities();
int maxTotalPointsActivityId = 
    UserActivities
    .GroupBy(ua => ua.ActivityId)
    .OrderByDescending(uaGp => uaGp.Sum(ua => ua.Points))
    .First()
    .Key;

答案 2 :(得分:1)

如果您只想要一个结果,即使有多个积分最多的活动......

var activityWithMostPoints = db.UserActivity
                            .GroupBy(a => a.ActivityId, 
                                     (k, g) => new { 
                                        ActivityId = k, 
                                        TotalPoints = g.Select(a => a.Points).Sum() 
                                    })
                            .OrderByDescending(a => a.TotalPoints)
                            .First();

您提供的SQL查询实际上会返回点数最多的所有活动。这有点复杂,可能效率低,具体取决于生成SQL ...

var activities = db.UserActivity
                    .GroupBy(a => a.ActivityId, 
                             (k, g) => new { 
                                ActivityId = k, 
                                TotalPoints = g.Select(a => a.Points).sum() 
                            });

 var activitiesWithMostPoints = activities
                                .Where(a => a.TotalPoints == activities.Max(a => a.TotalPoints));