C# 使用linq的日期范围内每月前5名客户机性能
我有一个表,我需要按月份以及其他一些列进行分组,并为整个日期范围选择每月前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
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));