あるグループにおける最新のレコードの全てのカラムを取得する SQL が次です。
SELECT * FROM members INNER JOIN ( # 対象のレコードのみが残る様に INNER JOIN で他レコードを落とします SELECT max(created_at) as last_created_at, # 最新を示す値 gender # グループを定める値 FROM members GROUP BY gender # グループ化 ) latest_gender_members ON latest_gender_members.last_created_at = members.created_at # 最新 AND latest_gender_members.gender = members.gender # かつ同グループ
情報を得たい対象と同範囲を探索するサブクエリを発行し、サブクエリの結果と INNER JOIN することで取得可能です。
処理を分解すると次の様になります。
まず内部のサブクエリで各グループを示す値と最新の値をとります
SELECT max(created_at) as last_created_at, # 最新を示す値 gender # グループを定める値 FROM members GROUP BY gender # グループ化
これを行うと例えば次の様な表を得られます。
# | last_created_at | gender |
---|---|---|
1 | 2021-01-28 09:52:23 | 0 |
2 | 2021-01-28 09:47:23 | 1 |
3 | 2021-01-28 09:09:19 | 2 |
4 | 2021-01-28 09:12:41 | 9 |
グループを示す値である gender と最新を示す値である last_created_at を持つあるグループにおける最新を示す行の集まりです。これを次の様にINNER JOINすることで最新でないレコードを省き、
FROM members INNER JOIN ( # gender, last_created_at カラムに最新を示す情報を持つ表 ) latest_gender_members ON latest_gender_members.last_created_at = members.created_at # 最新 AND latest_gender_members.gender = members.gender # かつ同グループ
SELECT * で最新のレコードについての全てを得ます。
SELECT *
この様にすることで最新のレコードのみを抽出できます。抽象版はうまく説明できないため省きましたが、最新以外にも様々な集約結果と組み合わせて使えます。