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日1秒あたり1行(= 86400行)。〜40列; すべて同じ形式
私は、列が指定する最大値と時間を取得する方法を探しています。

時間枠内で指定する列の最大値とそれに応じた時間を取得する方法を探しています。

何かのようなもの

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

動作しますが、列をパラメーターとして使用できません。

LINQソリューションまたはSPが最適です。

最大値を取得するためにデータセット全体を並べ替えるときにパフォーマンスを心配する必要がありますか?たぶんMAX関数はもっと速くなるでしょう。

アップデート

Timothy(tvanfossen)が提案したように、動的なlinqの方法で実装しようとしました

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

ただし、これはテーブルの最初の値を返します。これは、最大値ではなく、時間枠の最初の値を返します。SQLプロファイラーを見ると、ORDER句がないことがわかります。
何か案が?

UPDATE 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 に渡されるラムダ式。動的に選択された列を処理するには、次の 2 つのルートがあります。

まず、列の小さな固定セットがある場合は、式を分割して作成できます。

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

または、2 番目のオプション: 式 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

どうですか:

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 に答える
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 に答える