ユーザーへの通知テーブルで、各ユーザーの最新通知のレコードを取得したかった
order_byでいけると思ったがうまくいかなかった
当初の検索部分はこんな感じ
(CodeIgniter
使用)
$this->db
->where('deleted_at', NULL)
->order_by('noticed_at', 'DESC')
->group_by('user_id')
->get('notices')
->result('array');
発行されたクエリ ↓
SELECT *
FROM `notices`
WHERE `deleted_at` IS NULL
GROUP BY `user_id`
ORDER BY `noticed_at` DESC
CodeIgniterではORDER BYがGROUP BYの後に実行されちゃうからうまくいかない
集約関数 max を使用して解決
->order_by('noticed_at', 'DESC')
を->where('noticed_at = (select max(noticed_at) from notices)', NULL, FALSE)
に変更する
こんな感じ
$this->db
->where('deleted_at', NULL)
->where('noticed_at = (select max(noticed_at) from notices)', NULL, FALSE)
->group_by('user_id')
->get('notices')
->result('array');
発行されたクエリ ↓
SELECT *
FROM `notices`
WHERE `deleted_at` IS NULL
AND noticed_at = (select max(noticed_at) from notices)
GROUP BY `user_id`
ざっくり補足
where('noticed_at = (select max(noticed_at) from notices)', NULL, FALSE)
集約関数はwhere句で直接使えないので、サブクエリ(=入れ子になったSQL)を使用する
max
メソッドを使用すると、最大値を算出できるつまり、
(select max(noticed_at) from notices)
でnoticed_atの一番大きい値を算出してから、where
で条件指定している