ドキュメントの表があります (これは簡略化されたバージョンです):
id | ###変化### ###コンテンツ###||
---|---|---|
... | 2 | |
... | 1 | |
... | 1 | |
... | ID ごとに 1 つの行を選択し、最大のリビジョンのみを選択するにはどうすればよいですか? |
と
[2, 1, ..] の 2 つの行が含まれるはずです。 MySQL
を使用しています。
現在、while ループ内のチェックを使用して、結果セット内の古いリビジョンを検出して上書きしています。しかし、これが結果を達成する唯一の方法でしょうか?
の解決策はありませんか?
使用するコードはできるだけ少なくしたいと思っています...
私の意見では、これはよりシンプルで、読みやすく、保守しやすいです。IN
を使用して達成できます これを試して:### リーリー###一目見ただけで...###
句で
contentMAX
集計関数を使用するだけで済みます。リーリー
物事は決して単純ではありませんよね?列も必要であることに今気づきました。
SQL では、これは非常に一般的な問題です。特定のグループ化識別子に基づいて、特定の列の最大値を持つデータ行全体を検索します。私のキャリアの中で、この質問をよく聞いてきました。実際、これは私が現在の仕事の技術面接で答えた質問です。
この質問は実際に非常に一般的であるため、Stack Overflow コミュニティは特にこのタイプの質問に対処するためのタグを作成しました:
greatest-n-per-group。 基本的に、この問題を解決するには 2 つの方法があります:
単純な
グループ識別子、グループ内の最大値を使用しますサブクエリを使用して接続します
このアプローチでは、最初にサブクエリで
group-identifier, max-value-in-group(上ですでに解決済み) を見つけます。次に、等結合に
このアプローチでは、テーブルをそれ自体に結合したままにします。同等の接続はgroup-identifier
とmax-value-in-group
を使用して、テーブルをサブクエリと結合します。 リーリー左結合には自己結合を使用し、接続条件とフィルタリング条件を調整します
group-identifier
に配置されます。次に、2 つの賢いステップがあります:ステップ 1 を実行すると、実際に最大値を持つ行の右側に- NULL
が表示されます (これは - LEFT JOIN
つまり、最終的には次のようになります:
リーリー
###結論は###
どちらの方法でもまったく同じ結果が得られます。であることに注意してください)。次に、結合の結果をフィルタリングして、右側に
NULLを持つ行のみを表示します。
に
max-value-in-groupを持つ 2 つの行がある場合、これら 2 つの行は両方のメソッドの結果に表示されます。
どちらの方法も SQL ANSI と互換性があるため、好みの RDBMS の「フレーバー」に関係なく使用できます。
どちらの方法もパフォーマンスの点では非常に使いやすいですが、実際の状況は異なる場合があります (RDBMS、データベース構造、インデックスなど)。したがって、方法を選択するときは、
ベンチマーク
を使用してください。自分にとって最も合理的な方法を必ず選択してください。