像表
datetime a1 b1 x2 ...
07-01-2009 13:10 8 9 10
07-01-2009 13:11 8 8 2
07-01-2009 13:12 9 1 1
一整天每秒1行(= 86400行);约40列;全部相同的格式
我正在寻找一种检索最大值和指定列时间的方法。
我正在寻找一种方法来检索最大值和列的时间,以指定时间范围内。
就像是
Select top 1 time,a1 from table
where (datetime>=begin and datetime<end)
order by a1 desc
将工作,但我不能使用列作为参数。
LINQ解决方案或SP会很棒。
在对整个数据集进行排序以检索最大值时,我是否需要担心性能?也许MAX功能会更快。
更新
我尝试以动态linq方式实现它,就像Timothy(tvanfossen)建议的那样
Dim q2 = context.table _
.Where("t >= @0 AND t < @1", begin, end) _
.OrderBy("@0 desc", col) _
.Take(1) _
.Select(col)
但是这将返回表中的第一个值。这将返回时间范围内的第一个值,而不是最大值。查看SQL事件探查器,我发现没有ORDER子句。
任何的想法?
更新2
由于某种原因,替换值在orderby子句中不起作用。
.OrderBY(col +“ desc”)工作
如果希望列名是动态的,则可能要使用VS2008代码示例中的 Dynamic Linq 。然后,您可以指定要作为排序依据的列的名称。
var query = context.table
.Where( t = t.begin <= date && date < t.end )
.OrderBy( "a1 desc" )
.Take(1)
.SingleOrDefault();
在SQL中:
select max(a1)
from table
where (datetime>=begin and datetime<end)
您不需要排序,只需使用标准的聚合函数即可。为了能够动态选择列,您需要使用字符串连接来动态创建SQL,但要非常小心以确保列名确实是列名,而不是SQL注入。
在LINQ中,再次有一个聚合要使用:
var res = datacontext.Table
.Where(t => t.datetime >= begin && t.datetime < end)
.Max(t => t.a1);
传递给Max的lambda表达式选择要获取其最大值的列。要处理动态选择的列,有两种方法:
首先,您可以分段构建表达式,如果有少量固定的列集,则很好:
Expression<Func<TableType, ColumnType>> colSelector = null;
switch (column) {
case "a1":
colSelector = t => t.a1;
break;
case "b2":
colSelector = t => t.b2;
break;
...
}
var res = datacontext.Table
.Where(t => t.datetime >= begin && t.datetime < end)
.Max(colSelector);
或者,第二种选择:使用表达式API自己构建表达式。有关详细信息,请参见此处: http : //www.albahari.com/nutshell/predicatebuilder.aspx