C# 使用linq的日期范围内每月前5名客户机性能

C# 使用linq的日期范围内每月前5名客户机性能,c#,sql-server,linq,C#,Sql Server,Linq,我有一个表,我需要按月份以及其他一些列进行分组,并为整个日期范围选择每月前5个计数 Table | JobKeys - Id - Branch - RegisteredDate - ClientReference - (Extra Columns not needed for this task) 当前集团声明: db.JobKeys.Where(o => o.RegisteredDate >= fromDate && o.RegisteredD

我有一个表,我需要按月份以及其他一些列进行分组,并为整个日期范围选择每月前5个计数

Table | JobKeys  
- Id  
- Branch  
- RegisteredDate  
- ClientReference  
- (Extra Columns not needed for this task)
当前集团声明:

db.JobKeys.Where(o => o.RegisteredDate >= fromDate && o.RegisteredDate <= toDate).GroupBy(o => new{ o.Branch, o.ClientReference, YearMonth = o.RegisteredDate.Year + "/" + o.RegisteredDate.Month }).Select(o => new { o.Key.ClientReference, o.Key.Branch, o.Key.YearMonth, o.Count() })
但我需要它回来:

17/05 - Perth - TerryTaylors - 22
17/05 - Perth - TimmyToolies - 33
17/05 - Perth - BillyBobbies - 42
17/05 - Melbourne - PinkyPonkies - 19
17/05 - Melbourne - JanglyJunglies - 11
18/05 - Perth - TerryTaylors - 9
18/05 - Perth - TimmyToolies - 2
18/05 - Sydney - RinkleRankles - 15
18/05 - Melbourne - PinkyPonkies - 61
18/05 - Melbourne - JanglyJunglies - 99
我可以运行一个循环来从完整的数据集中提取数据,但这样做意味着要开始一个大规模的查询,然后在内存表中循环。表中有超过一百万条记录,而如果可能的话,我只希望在一个查询中提取所需的数据

using System;
using System.Linq;
using System.IO;
using System.Collections.Generic;

public class Test
{
    public string YearMonth {get;set;}
    public string Branch {get;set;}
    public string CIRef {get;set;}
    public int Count {get;set;}
}

class Program
{
    static void Main()
    {
        List<Test> Tests = new List<Test>
        {
            new Test
            {
                YearMonth = "17/05",
                Branch = "Perth",
                CIRef = "TerryTaylors",
                Count = 22
            },
            new Test
            {
                YearMonth = "17/05",
                Branch = "Perth",
                CIRef = "TimmyToolies",
                Count = 33
            },
            new Test
            {
                YearMonth = "17/05",
                Branch = "Perth",
                CIRef = "BillyBobbies",
                Count = 42
            },
            new Test
            {
                YearMonth = "17/05",
                Branch = "Sydney",
                CIRef = "RinkleRankles",
                Count = 10
            },
            new Test
            {
                YearMonth = "17/05",
                Branch = "Melbourne",
                CIRef = "PinkyPonkies",
                Count = 19
            },
            new Test
            {
                YearMonth = "17/05",
                Branch = "Melbourne",
                CIRef = "JanglyJunglies",
                Count = 11
            },
            new Test
            {
                YearMonth = "18/05",
                Branch = "Perth",
                CIRef = "TerryTaylors",
                Count = 9
            },
            new Test
            {
                YearMonth = "18/05",
                Branch = "Perth",
                CIRef = "TimmyToolies",
                Count = 2
            },
            new Test
            {
                YearMonth = "18/05",
                Branch = "Perth",
                CIRef = "BillyBobbies",
                Count = 1
            },
            new Test
            {
                YearMonth = "18/05",
                Branch = "Sydney",
                CIRef = "RinkleRankles",
                Count = 15
            },
            new Test
            {
                YearMonth = "18/05",
                Branch = "Melbourne",
                CIRef = "PinkyPonkies",
                Count = 61
            },
            new Test
            {
                YearMonth = "18/05",
                Branch = "Melbourne",
                CIRef = "JanglyJunglies",
                Count = 99
            }
        };

        var groupedBy = Tests.GroupBy(t => t.YearMonth)
                    .SelectMany(o => o.OrderByDescending(x => x.Count).Take(5));

        foreach(var c in groupedBy)
        {
            Console.WriteLine(c.YearMonth + " - " + c.Branch + " - " + c.CIRef + " - " + c.Count);
        }
    }
}
结果,

与:

我们按YearMonth属性分组,然后按计数降序排列每个集合,因此计数较高的集合位于顶部,只取前5个集合


完成后,您可以添加一个.ToList,也可以不添加,这取决于您下一步要做什么。

我相信在选择前5名之前,您必须至少按计数排序,但这样您就不会得到预期的结果Hey@MongZhu如果我这样做,它只会从整个列表集中返回5,我每个月都需要它日期范围内的每个月你有没有尝试过选择manyg=>g.OrderByo=>o.Count.Take5.ToList而不是选择…?你的预期结果的顺序真的很重要还是我的答案中的顺序足够好?@MongZhu一旦你做了。选择…,你现在正在处理一个包含所有结果的列表,所以如果你申请的话。在这个问题上,你只会得到5个结果,而不是每年5个。SelectMany和第二个分组正是我所需要的,谢谢heaps,现在正确地学习了一个新的linq函数,所以双倍奖金
using System;
using System.Linq;
using System.IO;
using System.Collections.Generic;

public class Test
{
    public string YearMonth {get;set;}
    public string Branch {get;set;}
    public string CIRef {get;set;}
    public int Count {get;set;}
}

class Program
{
    static void Main()
    {
        List<Test> Tests = new List<Test>
        {
            new Test
            {
                YearMonth = "17/05",
                Branch = "Perth",
                CIRef = "TerryTaylors",
                Count = 22
            },
            new Test
            {
                YearMonth = "17/05",
                Branch = "Perth",
                CIRef = "TimmyToolies",
                Count = 33
            },
            new Test
            {
                YearMonth = "17/05",
                Branch = "Perth",
                CIRef = "BillyBobbies",
                Count = 42
            },
            new Test
            {
                YearMonth = "17/05",
                Branch = "Sydney",
                CIRef = "RinkleRankles",
                Count = 10
            },
            new Test
            {
                YearMonth = "17/05",
                Branch = "Melbourne",
                CIRef = "PinkyPonkies",
                Count = 19
            },
            new Test
            {
                YearMonth = "17/05",
                Branch = "Melbourne",
                CIRef = "JanglyJunglies",
                Count = 11
            },
            new Test
            {
                YearMonth = "18/05",
                Branch = "Perth",
                CIRef = "TerryTaylors",
                Count = 9
            },
            new Test
            {
                YearMonth = "18/05",
                Branch = "Perth",
                CIRef = "TimmyToolies",
                Count = 2
            },
            new Test
            {
                YearMonth = "18/05",
                Branch = "Perth",
                CIRef = "BillyBobbies",
                Count = 1
            },
            new Test
            {
                YearMonth = "18/05",
                Branch = "Sydney",
                CIRef = "RinkleRankles",
                Count = 15
            },
            new Test
            {
                YearMonth = "18/05",
                Branch = "Melbourne",
                CIRef = "PinkyPonkies",
                Count = 61
            },
            new Test
            {
                YearMonth = "18/05",
                Branch = "Melbourne",
                CIRef = "JanglyJunglies",
                Count = 99
            }
        };

        var groupedBy = Tests.GroupBy(t => t.YearMonth)
                    .SelectMany(o => o.OrderByDescending(x => x.Count).Take(5));

        foreach(var c in groupedBy)
        {
            Console.WriteLine(c.YearMonth + " - " + c.Branch + " - " + c.CIRef + " - " + c.Count);
        }
    }
}
17/05 - Perth - BillyBobbies - 42
17/05 - Perth - TimmyToolies - 33
17/05 - Perth - TerryTaylors - 22
17/05 - Melbourne - PinkyPonkies - 19
17/05 - Melbourne - JanglyJunglies - 11
18/05 - Melbourne - JanglyJunglies - 99
18/05 - Melbourne - PinkyPonkies - 61
18/05 - Sydney - RinkleRankles - 15
18/05 - Perth - TerryTaylors - 9
18/05 - Perth - TimmyToolies - 2
var groupedBy = Tests.GroupBy(t => t.YearMonth)
      .SelectMany(o => o.OrderByDescending(x => x.Count).Take(5));