グループ化された各セットの最大値を含む行を取得するにはどうすればよいですか?
この質問に関して、過度に複雑なバリエーションをいくつか見てきましたが、どれも良い答えがありませんでした。できるだけ単純な例をまとめてみました。
以下のような、人物、グループ、年齢の列がある表があった場合、各グループの最年長者をどのように取得しますか? (グループ内で同点の場合は、アルファベット順の最初の結果になります)
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 つ以上の行と一致します。b
Group
Age
o
Age
b
を使用すると、グループ内で最も年長の人物 (グループ内で単独でいる人物を含む) が、からの sLEFT JOIN
でいっぱいの行(「グループ内で最も年齢が高い人物はいない」) と一致します。を使用すると、これらの行は一致せず、無視されます。NULL
b
INNER JOIN
この句は、 から抽出されたフィールドに がWHERE
含まれる行のみを保持します。これらは各グループの最年長者です。NULL
b
参考文献
この解決策と他の多くの解決策は本の中で説明されているSQL アンチパターン 第 1 巻: データベース プログラミングの落とし穴を回避する