Linq按月/年进行分组,过去12个月中的空月份

8 浏览
0 Comments

Linq按月/年进行分组,过去12个月中的空月份

如何使这个查询获取过去12个月的每月计数数据?我不想硬编码范围,我想使用当前日期DateTime.Now并从其中获取过去12个月的所有数据。我试图避免向数据库添加日历表,只使用LINQ来完成这个任务。有些月份可能没有任何数据,但是我仍然需要对这些月份进行计数,以得到0。例如,如果我的数据包含:

Date     Count
12/2/2013, 4
10/1/2014, 1
11/5/2014, 6

使用当前日期为11/9/2014,结果应该是:

11/2013, 0
12/1013, 4
 1/2014, 0
 2/2014, 0
 3/2014, 0
 4/2014, 0
 5/2014, 0
 6/2014, 0
 7/2014, 0
 8/2014, 0
 9/2014, 0
10/2014, 1
11/2014, 6

我无法使它工作。我认为问题出在我如何使用Range上,但我不确定。

TimeSpan ts = new TimeSpan(365, 0, 0, 0);
DateTime yearAgo = DateTime.Now.Subtract(ts);
var changesPerYearAndMonth =
    from year in Enumerable.Range(yearAgo.Year, 1)
    from month in Enumerable.Range(1, 12)
    let key = new { Year = year, Month = month }
    join revision in list on key
          equals new { revision.LocalTimeStamp.Year, 
                       revision.LocalTimeStamp.Month } into g
    select new { GroupCriteria = key, Count = g.Count() };

我修改了这个链接中的答案作为起点。

Linq: group by year and month, and manage empty months

我刚刚发现这篇文章是同样的问题,但没有答案。

Linq - group by datetime for previous 12 months - include empty months

0
0 Comments

Linq中的group by month/year with empty months for past 12 months问题是在对过去12个月的数据进行按月份和年份分组时,如果某些月份没有数据,仍然需要返回一个计数为0的结果。下面是问题的出现原因和解决方法。

问题的出现原因是数据可能在过去的某些月份为空,但是仍然需要返回一个计数为0的结果。解决方法是使用Linq的查询语法或链式语法,在进行分组之前先对数据进行筛选。

解决方法一:使用查询语法

// 假设list是一个DateTime类型的列表
list = new List();
DateTime aYearAgo = DateTime.Now.AddYears(-1);
var dateslastYear = from date in list
                 where date > aYearAgo
                 group date by new { date.Year, date.Month } into g
                 select new { GroupCriteria = g.Key, Count = g.Count() };

解决方法二:使用链式语法

dateslastYear = list.Where (d=>d>aYearAgo)
                    .GroupBy (date=>new{date.Year, date.Month });

解决方法三:如果要按年份和月份进行分组,包括不存在的记录,并且省略那些早于一年的记录,可以使用`Enumerable.Range`进行连接:

var thisYearPairs = from m in Enumerable.Range(1, DateTime.Now.Month)
                      select new { Year = DateTime.Now.Year, Month = m };
var lastYearPairs = from m in Enumerable.Range(DateTime.Now.Month, 12 - DateTime.Now.Month + 1)
                      select new { Year = DateTime.Now.Year - 1, Month = m };
var ymOuter = from ym in thisYearPairs.Union(lastYearPairs)
                join l in list on new { ym.Year, ym.Month } equals new { l.Year, l.Month } into oj
                from p in oj.DefaultIfEmpty()
                select new { a = ym, b = p == null ? DateTime.MinValue : p };
var ymGroup = from ym in ymOuter
                group ym by ym into g
                select new { GroupCriteria = g.Key.a, Count = g.Key.b == DateTime.MinValue ? 0 : g.Count() };

以上是解决Linq group by month/year with empty months for past 12 months问题的方法。通过在分组之前对数据进行筛选,可以确保即使某些月份没有数据,也能返回一个计数为0的结果。

0
0 Comments

Linq中的group by语句用于对数据进行分组,并且可以通过聚合函数对每个组进行计算。在这个问题中,需要按照月份和年份对数据进行分组,并且包括过去12个月中的空月份。

原因:

问题的原因是需要获取过去12个月的月份和年份,并且包括空的月份。代码中通过使用`Enumerable.Range`方法生成了一个范围为-12到0的整数序列,然后通过`Select`方法对每个整数进行操作,获取对应的月份和年份。然后,使用`GroupJoin`方法将数据列表和月份年份进行关联,并使用`Sum`函数对每个组中的计数进行求和。

解决方法:

为了确保正确获取过去12个月的月份和年份,并避免由于月末效应导致的错误,可以先将当前日期设置为月初。在代码中,通过将`now`日期的Day属性设置为1,然后将其添加到`now`日期的天数减去1的结果上,实现了将`now`日期移动到当月的月初。

然后,根据给定的示例数据列表和生成的月份年份列表,使用`GroupJoin`方法将它们关联在一起,并使用`Sum`函数对每个组中的计数进行求和。最后,通过遍历结果并打印每个月份、年份和计数,来展示问题的解决方法。

通过使用Linq的`GroupJoin`方法和`Sum`函数,以及对日期进行适当的处理,可以实现按照月份和年份进行分组,并包括过去12个月中的空月份的需求。

0
0 Comments

原因:问题的出现是因为原始代码中只获取了去年12个月的数据,而实际上需要获取最近的12个月的数据。

解决方法:可以使用Enumerable.Range和AddMonths方法来解决问题。具体代码如下:

var changesPerYearAndMonth =
    from month in Enumerable.Range(0, 12)
    let key = new { Year = DateTime.Now.AddMonths(-month).Year, Month = DateTime.Now.AddMonths(-month).Month }
    join revision in list on key
    equals new
    {
        revision.LocalTimeStamp.Year,
        revision.LocalTimeStamp.Month
    } into g
    select new { GroupCriteria = key, Count = g.Count() };

以上代码使用Enumerable.Range来生成一个包含最近12个月的序列,然后使用AddMonths方法来计算每个月的年份和月份。接着使用join将这个序列与原始数据进行连接,并根据年份和月份进行匹配。最后使用select来创建新的对象,包含了分组的条件和每个分组的计数。

通过以上的解决方法,可以实现按月份和年份进行分组,并且在过去的12个月中包含空的月份。

0