経緯
LaravelでGroupByを用いたSQLを作成した際、
集計した結果が正常に取得できず、沼った
問題のプログラム
$query = Table::newQuery();
$query->where($where);
$query->groupBy($groupColumn);
$query->count();
- 結果:集計結果が1になってしまう
- 集計結果に対して $query->get()->count(); では
ページャーなど limit, offset に問題が発生する - DB側で処理を完了させて高速化したい
やりたかったこと
-- 同じ条件でHITした件数を取得したい
SELECT COUNT(*)
FROM table_names
GROUP BY group_column
- データのwhere句は共通
- group_columnに対してGroupByを行った結果を表示する
- ->get()と同じ件数を->count()で取得させて正常に動作させたい
ページャーで集計して表示など、limit, offsetに相違なく動かしたい
原因
Laravelのcount()はどうやらサブクエリで処理しているらしく、
取得した件数をカウントしているわけではないため、
そのまま渡して実行するのはダメとのこと
SQLの処理結果に表示される取得件数と同じような取得方法だと思い込んでいたことが原因でした。
SELECT COUNT(*)
FROM (
-- $queryのSQL
SELECT *
FROM table_names
GROUP BY group_column
)
解決策
function dataCount() {
$query = $this->build();
if (isset($groupColumn) {
$query->distinct($groupColumn);
}
return $query->count();
}
function get() {
$query = $this->build();
if (isset($groupColumn) {
$query->groupBy($groupColumn);
}
return $query->get();
}
distinct関数を用いると正常に集計される。
その場合、groupByは不要になるので、
get()とcount()をする処理は別関数とし、同じ条件でgroupByを記述させることで解決