[MySQL]同グループ内で最新のデータを抽出したい
春眠暁を覚えずとはよく言ったものですね。kimoto です眠い。
今日はちょっとした小ネタです。
MySQL で、ログテーブルなどで、同一グループ内で最新データを取ってきたい時どうしよう?という話です。
何がしたいのかをまず説明します。
例えばこんな感じの行動ログのテーブルがあったとします(action_logs という名前とします)。
action_logs
+----+----------+----------------------+-------------+
| id | user_id | action_datetime | action_type |
+----+----------+----------------------+-------------+
| 1 | 1 | 2015-03-28 11:22:33 | AA |
| 2 | 2 | 2015-03-30 14:12:47 | BA |
| 3 | 1 | 2015-03-31 13:10:05 | CD |
| 4 | 3 | 2015-04-01 10:23:04 | CC |
| 5 | 3 | 2015-04-01 19:56:34 | BB |
| 6 | 1 | 2015-04-02 08:31:24 | AB |
| 7 | 2 | 2015-04-03 21:58:07 | BD |
| 8 | 2 | 2015-04-04 23:10:19 | DA |
+----+----------+----------------------+-------------+
このテーブル上では1、2、3というユーザのログがあります。
この中から、「それぞれのユーザの最終行動を知りたい」という時にどうするか、という感じですね。
まず、「最新ならGROUP BY user_id して、MAX(action_datetime) すればいいんじゃね?」と考えがちですが、それでは最新行動の「日時」しかとれません。
その時の「action_type」は?となるとこれでは持って来られないのです。
じゃあどうしよう。
多少強引ですが、同じテーブルを JOIN して、最新のもののみを持ってきましょう。
SELECT al_a.*
FROM action_logs AS al_a
WHERE al_a.id = (
SELECT al_b.id
FROM action_logs AS al_b
WHERE al_a.user_id = al_b.user_id
ORDER BY al_b.action_datetime DESC
LIMIT 1
)
同一ユーザのログ内でソートし、最新一件のみ持ってくるようにします。
action_logs
+----+----------+----------------------+-------------+
| id | user_id | action_datetime | action_type |
+----+----------+----------------------+-------------+
| 5 | 3 | 2015-04-01 19:56:34 | BB |
| 6 | 1 | 2015-04-02 08:31:24 | AB |
| 8 | 2 | 2015-04-04 23:10:19 | DA |
+----+----------+----------------------+-------------+
てことで、取ってきたいデータを取ってくることができました。
以上、小ネタでした。