一見...
必要なのはGROUP BY
だけです MAX
を含む句 集計関数:
SELECT id, MAX(rev)
FROM YourTable
GROUP BY id
そんなに簡単なことはありませんよね?
content
が必要だと気づきました 列も同様です。
これはSQLで非常によくある質問です。あるグループ識別子ごとに、列に最大値を持つ行のデータ全体を見つけます。私のキャリアの中でそれをたくさん聞いた。実際、それは私が現在の仕事の技術面接で答えた質問の1つでした。
実際、Stack Overflowコミュニティが次のような質問に対処するためだけに単一のタグを作成することは非常に一般的です:greatest-n-per-group」とタグ付けされた質問を表示 。
基本的に、その問題を解決するには2つのアプローチがあります。
単純なgroup-identifier, max-value-in-group
との結合 サブクエリ
このアプローチでは、最初にgroup-identifier, max-value-in-group
を見つけます。 (上記ですでに解決済み)サブクエリで。次に、両方のgroup-identifier
で同等にテーブルをサブクエリに結合します およびmax-value-in-group
:
SELECT a.id, a.rev, a.contents
FROM YourTable a
INNER JOIN (
SELECT id, MAX(rev) rev
FROM YourTable
GROUP BY id
) b ON a.id = b.id AND a.rev = b.rev
自己による左結合、結合条件とフィルターの調整
このアプローチでは、テーブルをそれ自体と結合したままにします。同等性はgroup-identifier
に含まれます 。次に、2つのスマートな動き:
- 2番目の結合条件は、左側の値が右側の値よりも小さいことです
- 手順1を実行すると、実際に最大値を持つ行は
NULL
になります。 右側(LEFT JOIN
、 覚えて?)。次に、結合された結果をフィルタリングして、右側がNULL
である行のみを表示します。 。
したがって、最終的には次のようになります:
SELECT a.*
FROM YourTable a
LEFT OUTER JOIN YourTable b
ON a.id = b.id AND a.rev < b.rev
WHERE b.id IS NULL;
結論
どちらのアプローチでもまったく同じ結果が得られます。
max-value-in-group
の行が2つある場合 group-identifier
の場合 、両方の行が両方のアプローチの結果になります。
どちらのアプローチもSQLANSIと互換性があるため、「フレーバー」に関係なく、お気に入りのRDBMSで機能します。
どちらのアプローチもパフォーマンスに優れていますが、マイレージは異なる場合があります(RDBMS、DB構造、インデックスなど)。したがって、一方のアプローチをもう一方のアプローチよりも選択する場合は、ベンチマーク 。そして、あなたにとって最も意味のあるものを選ぶようにしてください。