0

我正在数据表中获取员工的出勤详细信息。看起来像这样

Day       SwipeTime
12/31/2012  11AM
12/31/2012  1PM
12/31/2012  7PM
12/31/2012  8PM
1/1/2012    2PM
1/1/2012    7PM
1/1/2012    8PM
1/2/2012    10AM
1/2/2012    8PM

我需要显示总小时数 = lastswipe - firstwipe 的员工的日期和总小时数

我的结果看起来像

Day TotalHours
12/31/2012  9
1/1/2012    6
1/2/2012    12

所以我需要找到按日期分组的最小和最大滑动。请帮我写查询

4

2 回答 2

3

您可以使用Enumerable.GroupBy分组依据date。然后你可以创建一个Dictionary<DateTime,int>键是日期,值是该日期的总小时数:

Dictionary<DateTime,int> dateGroups = table.AsEnumerable()
    .GroupBy(r => r.Field<DateTime>("Date").Date)
    .Select(g => new{
        Date = g.Key, 
        TotalHours = g.Sum(r => 
               DateTime.ParseExact(r.Field<string>("SwipeTime"), 
                      "htt", CultureInfo.InvariantCulture).Hour)
    }).ToDictionary(x => x.Date, x => x.TotalHours);

编辑:所以,那是一TotalHours整天,现在是所需的最大-最小计算。您还将所需的时间跨度格式更改为“11:41 AM”。然后我会用它DateTime.Parse(str).TimeOfDay来获取时间跨度。

Dictionary<DateTime, int> dateGroups = table.AsEnumerable()
.GroupBy(r => r.Field<DateTime>("Date").Date)
.Select(g => new
{
    Date = g.Key,
    TotalHours = 
       (g.Max(r => DateTime.Parse(r.Field<string>("SwipeTime")).TimeOfDay)
      - g.Min(r => DateTime.Parse(r.Field<string>("SwipeTime")).TimeOfDay)).Hours
}).ToDictionary(x => x.Date, x => x.TotalHours);
于 2013-01-09T07:59:22.307 回答
2

在这个答案中,创建了一天的有序时间列表以避免两件事 - 两次解析所有行,并从解析的值创建两组以获得最大和最小项。我也不在分组前解析一天,因为相同的日期将具有相同的字符串值。

var query = from row in table.AsEnumerable()
            group row by row.Field<string>("Day") into g
            let times = g.Select(r => DateTime.Parse(r.Field<string>("SwipeTime")))
                         .OrderBy(t => t.TimeOfDay)
                         .ToList()
            select new
            {
                DateTime.Parse(g.Key).Date,
                (times.Last() - times.First()).TotalHours
            };

结果是具有两个属性的匿名对象的DateTime Date集合double TotalHours

于 2013-01-09T08:25:36.487 回答