表格如
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”)工作
答案 0 :(得分:2)
在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
答案 1 :(得分:1)
如果您希望列名称是动态的,则可能需要使用Dynamic Linq中的VS2008 code samples。然后,您可以指定要排序的列的名称。
var query = context.table
.Where( t = t.begin <= date && date < t.end )
.OrderBy( "a1 desc" )
.Take(1)
.SingleOrDefault();
答案 2 :(得分:0)
我认为这会奏效。基本上使用函数来返回列的顺序。
var result = Table
.OrderByDescending( row => GetColumnOfInterest(row) )
.First()
.dateTime;
int GetColumnOfInterest( Row row )
{
if ( ... )
{
return row.a1;
}
else if ( ... )
{
return row.b1;
}
}
答案 3 :(得分:0)
怎么样:
IEnumerable<Table> results = Table;
switch ( condition )
{
condition 1:
results = results.OrderByDescending( row => row.a1 );
condition 2:
results = results.OrderByDescending( row => row.a2 );
condition 3:
results = results.OrderByDescending( row => row.a3 );
....
}
var result = results.First().dateTime;