1. ホーム
  2. マイスル

[解決済み】グループ化されたSQL結果の各グループで最大値を持つレコードを取得する

2022-03-29 10:48:41

質問

グループ化された各セットの最大値を含む行はどのように取得するのですか?

この質問に対する複雑すぎるバリエーションをいくつか見ましたが、良い答えのものはありませんでした。そこで、できるだけシンプルな例を挙げてみました。

下のような表で、人、グループ、年齢の列がある場合、各グループの最年長者はどのように求めるか?(グループ内で同数の場合、アルファベット順の最初の結果が得られるはずです。)

Person | Group | Age
---
Bob  | 1     | 32  
Jill | 1     | 34  
Shawn| 1     | 42  
Jake | 2     | 29  
Paul | 2     | 36  
Laura| 2     | 39  

希望する結果セット。

Shawn | 1     | 42    
Laura | 2     | 39  

解決方法は?

mysqlで超簡単にできる方法があります。

select * 
from (select * from mytable order by `Group`, age desc, Person) x
group by `Group`

これは、mysqlでは以下のように許可されているためです。 ではなく グループバイカラムでないカラムを集約する場合、mysql は単に 最初 の行になります。解決策は、まず各グループで必要な行が最初に来るようにデータを並べ、次に値が必要な列でグループ化することです。

を探そうとする複雑なサブクエリを避けることができます。 max() また、同じ最大値を持つ行が複数ある場合、複数の行を返してしまうという問題もあります (他の回答がそうであるように)。

これは mysql専用 を解決することができます。私が知っている他のすべてのデータベースは、"non aggregated columns are not listed in group by clause"などのメッセージでSQL構文エラーを投げつけます。このソリューションでは 文書化されていない の動作を保証するためのテストを含めるとよいでしょう。 残る は、MySQL の将来のバージョンでこの動作が変更された場合にも動作します。

バージョン5.7に更新しました。

バージョン5.7以降では sql-mode の設定には ONLY_FULL_GROUP_BY をデフォルトで使用するため、この機能を実現するためには ではなく にはこのオプションがあります(サーバーのオプションファイルを編集して、この設定を削除してください)。