グループ化された各SQL結果の最大値レコードを取得します
P粉186904731
2023-08-20 18:10:21
<p>各グループの最大値を含む行を取得するにはどうすればよいですか? </p>
<p>非常に複雑なバリエーションをいくつか見ましたが、適切な答えを与えるものはありませんでした。最も単純な例を試してみました: </p>
<p>以下の表に人、グループ、年齢の列が含まれている場合、各グループの最年長者をどのように取得しますか? (グループ内で同点の場合は、アルファベット順で最初の結果が得られます) </p>
<pre class="brush:php;toolbar:false;">人 | グループ | 年齢
---
ボブ | 1 | 32
ジル | 1 | 34
ショーン| 1 | 42
ジェイク | 2 | 29
ポール | 2 | 36
ローラ| 2 | 39</pre>
<p>必要な結果セット: </p>
<pre class="brush:php;toolbar:false;">ショーン | 1 | 42
ローラ | 2 | 39</pre>
<p><br /></p>
正しい解決策は次のとおりです:
リーリー ###使い方:###の各行と、同じ
LEFT JOINGroup
列値およびより大きなAge
列値を持つb
のすべての行と一致します。一致する行。Age
列のグループ内で最大値を持たないo
の行は、b
の 1 つ以上の行と一致します。グループ内の最年長者 (単独の人も含む) と行
WHERENULL
fromb
( '年上の人はいないグループ内の年齢')。INNER JOIN を使用すると、これらの行は一致せず、無視されます。
句は、
『SQL アンチパターン 第 1 巻: データベース プログラミングの落とし穴の回避』b
から抽出されたフィールド内のNULL
を持つ行のみを保持します。彼らは各グループの最年長です。###参考文献###
このソリューションと他の多くのソリューションは、書籍で詳しく説明されています。
mysql でこれを行う非常に簡単な方法があります:
リーリーこのメソッドが機能するのは、mysql では列によるグループ化以外の集計を できないためです。その場合、mysql は 最初の行 のみを返します。解決策は、まずデータを希望する順序で並べ替えてから、希望する列ごとにグループ化することです。
複雑なサブクエリがmax()
などを見つけようとする問題を回避し、同じ最大値を持つ複数の行がある場合に複数の行を返す問題も回避します (他の回答はこれを行います) )。
注: これは、mysql の のみのソリューションです。私が知っている他のデータベースはすべて、「非集計列が group by 句にリストされていません」または同様のエラー メッセージを含む SQL 構文エラーをスローします。このソリューションは 文書化されていない 動作を使用しているため、より賢明な人は、MySQL の将来のバージョンでこの動作が変更された場合でも動作することを確認するテストを組み込むことをお勧めします。
バージョン 5.7 アップデート:sql-mode
設定にはデフォルトで ONLY_FULL_GROUP_BY
が含まれるため、これを機能させるには このオプションは使用しないでください (この設定を削除するには、サーバーのオプション ファイルを編集してください)。