2

これは、他のPartition By + Rankの質問と重複している可能性がありますが、これらの質問/回答のほとんどは、特定のビジネスロジックに固有のものであることがわかりました。私が探しているのは、次のタイプのクエリのより一般的なLINQバージョンです。

SELECT id,
       field1,
       field2,
       ROW_NUMBER() OVER (PARTITION BY id
                          ORDER BY field1 desc) ROWNUM
FROM someTable;

これを使用して行う非常に一般的なことは、次のようにラップすることです。

SELECT id,
       field1,
       field2
FROM (SELECT id,
      field1,
      field2,
      ROW_NUMBER() OVER (PARTITION BY id
                         ORDER BY field1 desc) ROWNUM
      FROM someTable)
WHERE ROWNUM = 1;

これは、各IDのfield1の最大値を含む行を返します。もちろん、順序をascに変更すると、最小値が返され、ランクを2に変更すると、2番目に高い/最小値などが取得されます。サーバー側で実行できるLINQクエリを記述して、同じ種類の機能?理想的には、上記と同じくらいのパフォーマンスを発揮するものです。

編集: Webを精査した後、さまざまな解決策を試しましたが、生成されたSQLにが含まれているため、以下のReedの回答と同じ問題が発生しますAPPLY

私が試したいくつかの例:

from p in db.someTable
group p by p.id into g
let mostRecent = g.OrderByDescending(o => o.field1).FirstOrDefault()
select new {
    g.Key,
    mostRecent
};

db.someTable
    .GroupBy(g => g.id, (a, b) => b.OrderByDescending(o => o.field1).Take(1))
    .SelectMany(m => m);

これらは両方とも、OUTER APPLYOracleがサポートしていないを使用するSQLコードと非常に似ていますが、同一ではありません。

4

2 に答える 2

5

次のようなことができるはずです。

var results = someTable
                 .GroupBy(row => row.id)
                 .Select(group => group.OrderByDescending(r => r.id).First());

3 番目に高い値が必要な場合は、次のようにすることができます。

var results = someTable
                 .GroupBy(row => row.id)
                 .Select(group => group.OrderByDescending(r => r.id).Skip(2).FirstOrDefault())
                 .Where(r => r != null); // Remove the groups that don't have 3 items
于 2013-03-08T17:02:46.687 に答える
1

別の方法として、field1それぞれの最大値を個別に取得するサブクエリを使用しますID

SELECT  a.*
FROM    someTable a
        INNER JOIN
        (
            SELECT  id, max(field1) max_field
            FROM    sometable
            GROUP   BY id
        ) b     ON a.id = b.ID AND
                    a.field1 = b.max_field

に変換するとLINQ:

from a in someTable
join b in 
    (
        from o in someTable
        group o by new {o.ID} into g
        select new 
        {
          g.Key.ID,
          max_field = g.Max(p => p.field1)
        }
    ) on new {a.ID, a.field1} equals new {b.ID, field1 = b.max_field}
select a
于 2013-03-08T17:05:14.777 に答える