バックエンドとフロントエンドを行き来するWEBプログラマ―のメモ帳

WEBプログラマ―。バックエンドはPHP, MySQL, CentOS系, フロントエンドはJavaScript, jQuery, HTML, CSSで仕事してます。

LaravelのEloquentで集計関数Count()などを使うとき

LaravelのEloquentで集計関数を使いたい

データの準備

例えば、Tagsテーブルと、タグと写真を紐づける中間テーブルのTagmapsテーブルがあるとします。

・Tags
f:id:mashiro_ruka:20190702210612p:plain

・Tagmaps
f:id:mashiro_ruka:20190702210557p:plain

これを使って、タグ数表示を作りたいとします。

f:id:mashiro_ruka:20190703162306p:plain

その場合は、タグの数を集計する必要があります。
f:id:mashiro_ruka:20190702211752p:plain
そこでLaravelのEloquentで集計しようとしましたが、

<?php
//~略~
$tag_count_list = \DB::table('tagmaps')
            ->join('tags', 'tagmaps.tag_id', '=', 'tags.id')
            ->select('count(*), tags.name')
            ->groupBy('tag_id')
            ->orderBy('count(*)', 'desc')
            ->get();

select('count(*), ...')でエラー

ここで、上のように、Laravelで、集計関数をそのままSelectに放り込んでしまうとエラーが出ます。

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'count(*), tags.name' in 'field list' (SQL: select `count(*), tag ~略~

解決策 DB::raw('count(*) as tag_count, ~')

これを解決するには、

<?php
//~略~
->select('count(*), tags.name')

を下のように変えます。

<?php
//~略~
->select(DB::raw('count(*) as tag_count, tags.name'))
<?php
//~略~
$tag_count_list = DB::table('tagmaps')
->join('tags', 'tagmaps.tag_id', '=', 'tags.id')
->select(DB::raw('count(*) as tag_count, tags.name'))
->groupBy('tagmaps.tag_id')
->orderBy('tag_count', 'desc')
->get();

bladeファイルでは以下のように{{ $tag_count->tag_count }}で数が取得できるようになりました。

@foreach($tag_count_list as $tag_count)
  <a href="javascript:void(0)" onclick="this.parentNode.submit()" class="btn-tag m-1">
    {{ $tag_count->name }} ({{ $tag_count->tag_count }})
  </a>
@endforeach

参考サイト

yoshinorin.net