C# 使用LINQ按n天对数据分组
我有以下课程:C# 使用LINQ按n天对数据分组,c#,linq,C#,Linq,我有以下课程: public class TotalPaymentStatistics { public DateTime RegisteredAt { get; set; } public double TotalAmount { get; set; } } <pre> void Main() { var items = new List<TotalPaymentStatistics>() { new Tot
public class TotalPaymentStatistics
{
public DateTime RegisteredAt { get; set; }
public double TotalAmount { get; set; }
}
<pre>
void Main()
{
var items = new List<TotalPaymentStatistics>()
{
new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,1),TotalAmount = 120},
new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,2),TotalAmount = 120},
new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,3),TotalAmount = 120},
new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,4),TotalAmount = 120},
new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,5),TotalAmount = 120},
new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,6),TotalAmount = 120},
new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,7),TotalAmount = 120},
new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,8),TotalAmount = 120},
new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,9),TotalAmount = 120},
new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,10),TotalAmount = 120},
};
DateTime day0 = items[0].RegisteredAt.AddDays(-1);
var q = items
.GroupBy(x => ((int)((x.RegisteredAt.Subtract(day0).TotalDays-1) / 5)))
.Select(x => new {
x.Key,
Date = day0.AddDays(x.Key*5+1),
Amount = x.Sum(y => y.TotalAmount)
});
foreach(var item in q)
{
Console.WriteLine($"{item.Date.ToString("yyyy-MM-dd")} {item.Amount}");
}
}
// Define other methods and classes here
public class TotalPaymentStatistics
{
public DateTime RegisteredAt { get; set; }
public double TotalAmount { get; set; }
}
</pre>
此外,我还将以下示例数据存储在数据库中:
2021-01-01 | 120
2021-01-02 | 120
2021-01-03 | 120
2021-01-04 | 120
2021-01-05 | 120
2021-01-06 | 120
2021-01-07 | 120
2021-01-08 | 120
2021-01-09 | 120
2021-01-10 | 120
如何以这样的方式对此类的对象进行分组,当我传递参数时,例如5,(5-是一个时间框架,意味着我希望在整个集合中每5天接收一次汇总数据),我将收到以下结果:
2021-01-01 600
2021-01-05 600
提前感谢您可以试试这个。假设您的dbcontext类是_context,并将DaysCount作为int类型添加到模型中进行天数计数,那么您可以编写为
_context.yourTables.GroupBy(x=>x.RegisteredAt.Date).select(t=>new TotalPaymentStatistics (){
RegisteredAt =t.Key,
TotalAmount =t.Sum(s=>s.TotalAmount),
DaysCount = t.Count()
}).ToList();
普遍的做法是只使用四舍五入到最接近的值。您可以通过这种方式指定任何时间间隔。例如: 然后你可以:
var groupInterval = TimeSpan.FromDays(5);
var groups = input
.GroupBy(x=> x.RegisteredAt.Floor(groupInterval))
.Select(x=>
new
{
date = x.Key,
sum = x.Sum(y=> y.TotalAmount)
});
通过指定起始班次或使用下限/上限/舍入方法,您可以稍微调整它以获得所需的组。使用简单的分区:数据是有序的,并且至少有一个元素
static IEnumerable<List<T>> Partition<T>(List<T> input, Func<T, DateTime> DateSelector, TimeSpan partitionSize)
{
var partitionEnd = DateSelector(input.First()).Add(partitionSize);
var partition = new List<T>();
foreach (var element in input)
{
var dt = DateSelector(element);
if (dt >= partitionEnd)
{
yield return partition;
partition = new List<T>();
partitionEnd = dt.Add(partitionSize);
}
partition.Add(element);
}
yield return partition;
}
现场演示
结果:
日期
数量
01/01/2021 00:00:00
600
01/06/2021 00:00:00
600
void Main()
{
var items=新列表()
{
new TotalPaymentStatistics(){RegisteredAt=new DateTime(2021,1,1),TotalAmount=120},
new TotalPaymentStatistics(){RegisteredAt=new DateTime(2021,1,2),TotalAmount=120},
new TotalPaymentStatistics(){RegisteredAt=new DateTime(2021,1,3),TotalAmount=120},
new TotalPaymentStatistics(){RegisteredAt=new DateTime(2021,1,4),TotalAmount=120},
new TotalPaymentStatistics(){RegisteredAt=new DateTime(2021,1,5),TotalAmount=120},
new TotalPaymentStatistics(){RegisteredAt=new DateTime(2021,1,6),TotalAmount=120},
new TotalPaymentStatistics(){RegisteredAt=new DateTime(2021,1,7),TotalAmount=120},
new TotalPaymentStatistics(){RegisteredAt=new DateTime(2021,1,8),TotalAmount=120},
new TotalPaymentStatistics(){RegisteredAt=new DateTime(2021,1,9),TotalAmount=120},
new TotalPaymentStatistics(){RegisteredAt=new DateTime(2021,1,10),TotalAmount=120},
};
DateTime day0=项目[0]。RegisteredAt.AddDays(-1);
var q=项目
.GroupBy(x=>((int)((x.RegisteredAt.Subtract(day0.TotalDays-1)/5)))
.选择(x=>new{
x、 钥匙,
日期=第0天。添加天数(x.Key*5+1),
金额=x.Sum(y=>y.TotalAmount)
});
foreach(q中的var项目)
{
Console.WriteLine($“{item.Date.ToString(“yyyy-MM-dd”)}{item.Amount}”);
}
}
//在此处定义其他方法和类
公共类TotalPaymentStatistics
{
公共日期时间注册表数据{get;set;}
公共双重合计金额{get;set;}
}
这将给你:
2021-01-01 600
2021-01-06 600
.GroupBy(p=>p.RegisteredAt.Date).Take(nDays).选择(g=>newtotalpaymentstatistics{RegisteredAt=g.Key,TotalAmount=g.Sum(i=>i.TotalAmount))
?到目前为止您尝试了什么?是否有尝试?如果我希望它每5天分组一次怎么办?这将返回我每天分组的数据。我建议您编辑您的问题,以明确您的问题。“当我传递参数时,例如5”当然需要澄清。正如你如何为他们两个都得到600。如果5是时间框架,那么第一个框架是从1到5。是从6到10。可以使用手指索引来检查^^^,但我在哪里指定天数、时间框架?@mSwierkot我在上面的模型中进行了编辑以放置天数计数,并在查询中进行了更改以获得它。
<pre>
void Main()
{
var items = new List<TotalPaymentStatistics>()
{
new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,1),TotalAmount = 120},
new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,2),TotalAmount = 120},
new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,3),TotalAmount = 120},
new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,4),TotalAmount = 120},
new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,5),TotalAmount = 120},
new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,6),TotalAmount = 120},
new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,7),TotalAmount = 120},
new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,8),TotalAmount = 120},
new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,9),TotalAmount = 120},
new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,10),TotalAmount = 120},
};
DateTime day0 = items[0].RegisteredAt.AddDays(-1);
var q = items
.GroupBy(x => ((int)((x.RegisteredAt.Subtract(day0).TotalDays-1) / 5)))
.Select(x => new {
x.Key,
Date = day0.AddDays(x.Key*5+1),
Amount = x.Sum(y => y.TotalAmount)
});
foreach(var item in q)
{
Console.WriteLine($"{item.Date.ToString("yyyy-MM-dd")} {item.Amount}");
}
}
// Define other methods and classes here
public class TotalPaymentStatistics
{
public DateTime RegisteredAt { get; set; }
public double TotalAmount { get; set; }
}
</pre>