使用LINQ C#按小时间隔汇总值

时间:2019-11-19 08:52:14

标签: c# linq aggregate-functions

我从API获得以下JSON结果。

[
    {
        "ID": "1",
        "Value" : "10",
        "TimeStamp": "2019-10-21 00:00:00"

    },
    {
        "ID": "1",
        "Value": "10",
        "TimeStamp": "2019-10-21 00:15:00"

    },
    {
        "ID": "1",
        "Value": "10",
        "TimeStamp": "2019-10-21 00:30:00"
    },
    {
        "ID": "1",
        "ResultValue": "10",
        "TimeStamp": "2019-10-21 00:45:00"
    },
    {
        "ID": "1",
        "Value": "20",
        "TimeStamp": "2019-10-21 01:00:00"

    },
    {
        "ID": "1",
        "Value": "10",
        "TimeStamp": "2019-10-21 01:15:00"

    },
    {
        "ID": "1",
        "Value": "10",
        "TimeStamp": "2019-10-21 01:30:00"
    },
    {
        "ID": "1",
        "Value": "10",
        "TimeStamp": "2019-10-21 01:45:00"
    },
    {
        "ID": "1",
        "Value": "30",
        "TimeStamp": "2019-10-21 02:00:00"
    }
]

我正在尝试使用下面的LINQ查询显示每小时汇总

var aggList = items.GroupBy(u => new { u.ID, u.TimeStamp.Date, u.TimeStamp.Hour })
                            .Select(g => new TestData
                            {
                                ID = g.Key.ID,
                                TimeStamp = g.Key.Date.AddHours(g.Key.Hour),
                                Value = g.Sum(k => k.Value)
                            }).ToList();

给出的结果为

  ID : 1
    TotalValue : 40
    TimeStamp : 21.10.2019 00:00:00

    ID : 1
    TotalValue : 50
    TimeStamp : 21.10.2019 01:00:00

我的LINQ查询应该是什么,如果我希望每小时的汇总从15分钟而不是0分钟开始考虑

像第一个小时一样应该具有

2019-10-21 00:15:00 - 10
2019-10-21 00:30:00 - 10
2019-10-21 00:45:00 - 10
2019-10-21 01:00:00 - 20

预期结果应该是

        ID : 1
        TotalValue : 50
        TimeStamp : 21.10.2019 00:00:00

        ID : 1
        TotalValue : 60
        TimeStamp : 21.10.2019 01:00:00

3 个答案:

答案 0 :(得分:4)

var aggList = items.GroupBy(u => new { u.ID, u.TimeStamp.AddMinutes(-15).Date, u.TimeStamp.AddMinutes(-15).Hour })
                            .Select(g => new TestData
                            {
                                ID = g.Key.ID,
                                TimeStamp = g.Key.Date.AddHours(g.Key.Hour),
                                Value = g.Sum(k => k.Value)
                            }).ToList();

答案 1 :(得分:2)

您可以移动Timestamp以获得效果。代替

items.GroupBy(u => new { u.ID, u.TimeStamp.Date, u.TimeStamp.Hour })

您将过去用于分组的时间更改为过去的15分钟,因此每小时前15分钟的所有时间都移到了早一点。

items.GroupBy(u => new { u.ID, u.TimeStamp.AddMinutes(-15).Date, u.TimeStamp.AddMinutes(-15).Hour })

答案 2 :(得分:0)

“如果我希望每小时汇总从15分钟开始考虑,而不是从0分钟开始考虑” 。您可以将小时增加15分钟,然后将其分组。

public class ApiResult
{
    public int ID { get; set; }
    public int Value { get; set; }
    public DateTime TimeStamp { get; set; }
}

var result = JsonConvert.DeserializeObject<IList<ApiResult>>(File.ReadAllText("../../../data.json"));

var AggValues = result.GroupBy(x => new
{
    x.ID,
    x.TimeStamp.AddMinutes(15).Date,
    x.TimeStamp.AddMinutes(15).Hour,
    x.Value
}).Select(x => new ApiResult
{
    ID = x.Key.ID,
    TimeStamp = x.Key.Date.AddHours(x.Key.Hour),
    Value = x.Sum(sum => sum.Value)
});

foreach(var i in AggValues)
{
    Console.WriteLine(i.ID + " " + i.Value + " " + i.TimeStamp);
}

输出:

1 30 2019-10-21 00:00:00
1 0 2019-10-21 01:00:00
1 20 2019-10-21 01:00:00
1 20 2019-10-21 01:00:00
1 10 2019-10-21 02:00:00
1 30 2019-10-21 02:00:00