LINQ 查询或存储过程返回指定列中的最大值

发布于 2024-07-25 22:58:08 字数 959 浏览 11 评论 0原文

的表

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

Table like

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 row per second for a whole day (=86400 rows); ~40 columns; all same format
I'm looking for a way to retrieve a max value and the time for a column to specify.

I'm looking for a way to retrive a max value and the according time for a column to specify within a timeframe.

Something like

Select top 1 time,a1 from table
    where (datetime>=begin and datetime<end) 
    order by a1 desc   

will work but I cannot use the column as a parameter.

A LINQ solution or a SP would be great.

Do I have to worry about performance when sorting a whole dataset to retrieve a max value? Maybe MAX function will be faster.

UPDATE

I tried to implement it the dynamic linq way, like Timothy (tvanfossen) suggested

Dim q2 = context.table _
  .Where("t >= @0 AND t < @1", begin, end) _
  .OrderBy("@0 desc", col) _
  .Take(1) _
  .Select(col)

BUT this returns the first value in the table.
This returns the first value in the time frame and not the max value. Looking at the SQL profiler I see that there is no ORDER clause.
Any idea?

UPDATE 2
For some reason the substitution value does not work in the orderby clause.
.OrderBY (col + " desc") works

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

幼儿园老大 2024-08-01 22:58:08

在 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

In SQL:

select max(a1)
from table
where (datetime>=begin and datetime<end) 

You don't need to sort, just use the standard aggregate function. To be able to choose the column dynamically you need to create the SQL dynamically, with string concatenation but be very careful to ensure the column name is really a column name, and not SQL injection.

In LINQ, again there is an aggregate to use:

var res = datacontext.Table
                     .Where(t => t.datetime >= begin && t.datetime < end)
                     .Max(t => t.a1);

The lambda expression passed to Max selecting the column to get the maximum value of. To handle the dynamically selected column there are two routes:

First, you could build the expression in pieces, good if there is a small fixed set of columns:

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);

Or, second option: build the Expression yourself with the expression API. See here for details: http://www.albahari.com/nutshell/predicatebuilder.aspx

知足的幸福 2024-08-01 22:58:08

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

var query = context.table
                   .Where( t = t.begin <= date && date < t.end )
                   .OrderBy( "a1 desc" )
                   .Take(1)
                   .SingleOrDefault();

If you want the column name to be dynamic, you might want to use Dynamic Linq from the VS2008 code samples. Then you can specify the name of the column to sort by.

var query = context.table
                   .Where( t = t.begin <= date && date < t.end )
                   .OrderBy( "a1 desc" )
                   .Take(1)
                   .SingleOrDefault();
墨离汐 2024-08-01 22:58:08

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

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

int GetColumnOfInterest( Row row )
{
   if ( ... )
   {
      return row.a1;
   }
   else if ( ... )
   {
      return row.b1;
   }
}

I think this will work. Basically use a function to return the column to order by.

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

int GetColumnOfInterest( Row row )
{
   if ( ... )
   {
      return row.a1;
   }
   else if ( ... )
   {
      return row.b1;
   }
}
治碍 2024-08-01 22:58:08

怎么样:

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;

How about:

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文