我正在一个数据表中获取员工的考勤详细信息。它看起来像这样
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
我需要显示一个雇员的日期和总小时数其中totalhours = lastswipe - firstwipe
我的结果看起来像
Day TotalHours
12/31/2012 9
1/1/2012 6
1/2/2012 12
所以我需要找到按日期分组的最小和最大滑动。请帮我写查询
可以使用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);
Edit:所以,这是一整天的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);
在这个答案中,创建一天的有序时间列表是为了避免两件事—解析所有行两次,并从解析的值创建两个集合以获得最大和最小项。此外,在分组之前我没有解析日期,因为相同的日期将具有相同的字符串值。
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
的匿名对象的集合