C# 这个按小时平均和分组的LINQ查询写得有效吗?
这是我第一个真实的LINQ到SQL查询。我想知道我是否犯了任何明显的大错误 我有一个包含数据、dataTypeID、machineID和日期戳的中大型(2M+记录,每天增加13k)表。我想在4小时内得到所有机器和特定数据类型的平均、最小和最大数据,可以追溯到28天 例如 DateTimeAvgMinMaxC# 这个按小时平均和分组的LINQ查询写得有效吗?,c#,linq-to-sql,group-by,aggregate-functions,C#,Linq To Sql,Group By,Aggregate Functions,这是我第一个真实的LINQ到SQL查询。我想知道我是否犯了任何明显的大错误 我有一个包含数据、dataTypeID、machineID和日期戳的中大型(2M+记录,每天增加13k)表。我想在4小时内得到所有机器和特定数据类型的平均、最小和最大数据,可以追溯到28天 例如 DateTimeAvgMinMax 2010年1月1日12:00AM74.272.175.7 2010年1月1日04:00AM74.573.176.2 2010年1月1日08:00AM73.771.574.2 2010年1月1日
2010年1月1日12:00AM74.272.175.7
2010年1月1日04:00AM74.573.176.2
2010年1月1日08:00AM73.771.574.2
2010年1月1日12:00PM73.271.276.1
等等…
2010年1月28日12:00AM73.171.375.5
到目前为止,我只能按1小时的增量对平均值进行分组,但如果备选方案过于混乱,我可能可以处理这个问题 代码:
如果希望以4小时为增量,请将小时除以4(使用整数除法),然后在创建新的datetime元素时乘以4。注意,您可以简单地使用需要年、月、日、小时、分钟和秒的构造函数,而不是构造字符串并将其转换
var q =
from d in DataPointTable
where d.dateStamp > DateTime.Now.AddDays(-28) && (d.dataTypeID == (int)dataType + 1)
group d by new {
d.dateStamp.Year,
d.dateStamp.Month,
d.dateStamp.Day,
Hour = d.dateStamp.Hour / 4
} into groupedData
orderby groupedData.Key.Year, groupedData.Key.Month, groupedData.Key.Day, groupedData.Key.Hour ascending
select new {
date = new DateTime(
groupedData.Key.Year,
groupedData.Key.Month,
groupedData.Key.Day,
(groupedData.Key.Hour * 4),
0, 0),
avg = groupedData.Average(d => d.data),
max = groupedData.Max(d => d.data),
min = groupedData.Min(d => d.data)
};
为了提高效率,您可能需要考虑在<代码> DATESTAMP 列上添加索引。考虑到您只选择了一个可能很小的日期范围,使用索引应该是一个显著的优势。我希望查询计划对第一个日期进行索引搜索,使之更快。
谢谢您的建议。我试过“d.dateStamp.Hour/4”,但它不合法。VS2008的意思是:“匿名类型成员声明程序无效。匿名类型成员必须使用成员分配、简单名称或成员访问权限声明。”var q =
from d in DataPointTable
where d.dateStamp > DateTime.Now.AddDays(-28) && (d.dataTypeID == (int)dataType + 1)
group d by new {
d.dateStamp.Year,
d.dateStamp.Month,
d.dateStamp.Day,
Hour = d.dateStamp.Hour / 4
} into groupedData
orderby groupedData.Key.Year, groupedData.Key.Month, groupedData.Key.Day, groupedData.Key.Hour ascending
select new {
date = new DateTime(
groupedData.Key.Year,
groupedData.Key.Month,
groupedData.Key.Day,
(groupedData.Key.Hour * 4),
0, 0),
avg = groupedData.Average(d => d.data),
max = groupedData.Max(d => d.data),
min = groupedData.Min(d => d.data)
};