c# - 使用 linq 在某个日期范围内每月排名前 5 的客户端性能

标签 c# sql-server linq

我有一个表格,需要按 MonthYear(以及其他一些列)进行分组,并选择整个日期范围内每个 MonthYear 的前 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() })

这为我提供了每个客户在某个日期范围内每月有多少工作的完整列表,但是从这个列表中我只想要每个年月的前 5 个客户。

即目前它将返回类似于以下内容的内容
YearMonth - 分支 - ClRef - 计数

17/05 - Perth - TerryTaylors - 22
17/05 - Perth - TimmyToolies - 33
17/05 - Perth - BillyBobbies - 42
17/05 - Sydney - RinkleRankles - 10
17/05 - Melbourne - PinkyPonkies - 19
17/05 - Melbourne - JanglyJunglies - 11
18/05 - Perth - TerryTaylors - 9
18/05 - Perth - TimmyToolies - 2
18/05 - Perth - BillyBobbies - 1
18/05 - Sydney - RinkleRankles - 15
18/05 - Melbourne - PinkyPonkies - 61
18/05 - Melbourne - JanglyJunglies - 99

但我需要它返回:

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);
        }
    }
}

这给了我:

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));

我们按YearMonth 属性进行分组,然后按Count 对每个集合进行排序(使用降序,因此具有较高 Count 的集合Count 在顶部)并只取其中的前 5 个。

完成此操作后,您可以添加或不添加 .ToList(),具体取决于您下一步要执行的操作。

关于c# - 使用 linq 在某个日期范围内每月排名前 5 的客户端性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48900432/

相关文章:

c# - 系统.Data.SqlClient.SqlException : 'Incorrect syntax near ' )'.' is that sql query error or something?

c# - 多对多关系的 LINQ to SQL 查询

c# - 如何保护接口(interface)实现?

c# - 仅在 3.5 中从 List<T> 到 IEnumerable<T> 的 InvalidCastException

sql-server - 如何从本地电脑连接到SQL Server数据库?

c# - 如何将 NULL 值插入数据库

C# 通过linq to xml调用值

c# - groupby 时不能隐式转换类型

c# - 站点地图安全修整引发 SQL 错误

c# - 添加 HttpClient header 会生成具有某些值的 FormatException