グループ化されたSQL結果の各グループの最大値を持つレコードを取得する 質問する

グループ化されたSQL結果の各グループの最大値を持つレコードを取得する 質問する

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

この質問に関して、過度に複雑なバリエーションをいくつか見てきましたが、どれも良い答えがありませんでした。できるだけ単純な例をまとめてみました。

以下のような、人物、グループ、年齢の列がある表があった場合、各グループの最年長者をどのように取得しますか? (グループ内で同点の場合は、アルファベット順の最初の結果になります)

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  

ベストアンサー1

正しい解決策は次のとおりです。

SELECT o.*
FROM `Persons` o                    # 'o' from 'oldest person in group'
  LEFT JOIN `Persons` b             # 'b' from 'bigger age'
      ON o.Group = b.Group AND o.Age < b.Age
WHERE b.Age is NULL                 # bigger age not found

使い方:

これは、列 に同じ値があり、列 に大きな値があるoのすべての行との各行を一致させます。列 にグループの最大値がないの行は、の 1 つ以上の行と一致します。bGroupAgeoAgeb

を使用すると、グループ内で最も年長の人物 (グループ内で単独でいる人物を含む) が、からの sLEFT JOINでいっぱいの行(「グループ内で最も年齢が高い人物はいない」) と一致します。を使用すると、これらの行は一致せず、無視されます。NULLb
INNER JOIN

この句は、 から抽出されたフィールドに がWHERE含まれる行のみを保持します。これらは各グループの最年長者です。NULLb

参考文献

この解決策と他の多くの解決策は本の中で説明されているSQL アンチパターン 第 1 巻: データベース プログラミングの落とし穴を回避する

おすすめ記事