2

表如

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") 有效

4

4 回答 4

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

于 2009-07-02T14:49:28.840 回答
1

如果您希望列名是动态的,您可能需要使用VS2008 代码示例中Dynamic Linq。然后您可以指定要排序的列的名称。

var query = context.table
                   .Where( t = t.begin <= date && date < t.end )
                   .OrderBy( "a1 desc" )
                   .Take(1)
                   .SingleOrDefault();
于 2009-07-02T14:48:21.153 回答
0

我认为这会奏效。基本上使用一个函数来返回要排序的列。

var result = Table
                .OrderByDescending( row => GetColumnOfInterest(row) )
                .First()
                .dateTime;

int GetColumnOfInterest( Row row )
{
   if ( ... )
   {
      return row.a1;
   }
   else if ( ... )
   {
      return row.b1;
   }
}
于 2009-07-02T14:50:30.180 回答
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;
于 2009-07-02T17:10:24.780 回答