質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.37%

Laravelのクエリビルダが発行するSQLは正しいのに、Laravel上でエラーになってしまう。

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 3,876

score 12

やりたいこと

サブクエリでschedule_user.attendanceの人数を数えてscheduleテーブルに外部結合をしたい。

環境

$ php --version
PHP 7.1.31 (cli) (built: Jul 31 2019 08:44:15) ( ZTS MSVC14 (Visual C++ 2015) x64 )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2018 Zend Technologies

$ composer --version
Composer version 1.9.0 2019-08-02 20:55:32

$ php artisan --version
Laravel Framework 5.8.31

$ MySQL --version
Your MySQL connection id is 11
Server version: 5.7.27-log MySQL Community Server (GPL)

 

生成したいSQL(cmdで試したところ通ります)

select * from `schedules` left JOIN (
    select `schedule_id`, count(attendance) as user_count from `schedule_user` where `attendance` = 1)
as `schedule_user` on `schedules`.`id` = `schedule_user`.`schedule_id`

 

発生している問題・エラーメッセージ

SQLSTATE[42000]: Syntax error or access violation: 1140 In aggregated query without GROUP BY,
 expression #1 of SELECT list contains nonaggregated column 'clubs.schedule_user.schedule_id';
 this is incompatible with sql_mode=only_full_group_by 
(SQL: select * from `schedules` left join (
select `schedule_id`, count(attendance) as user_count from `schedule_user` where `attendance` = 1
) as `schedule_user` on `schedules`.`id` = `schedule_user`.`schedule_id`)

該当のソースコード

$count_query = \DB::table('schedule_user')
    ->select('schedule_id', \DB::raw('count(attendance) as user_count'))
    ->where('attendance', 1);

 $items = \DB::table('schedules')
    ->leftJoinSub($count_query, 'schedule_user', function($join) {
        $join->on('schedules.id', '=', 'schedule_user.schedule_id');})
    ->get();
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

SELECT の並びに カラム1 と集合関数(今回はcount)を使った場合は group by カラム1 と指定して、文法的に明確に カラム1毎の count を指定しなければなりません。

select * from `schedules` left JOIN (
    select `schedule_id`, count(attendance) as user_count from `schedule_user` where `attendance` = 1)
as `schedule_user` on `schedules`.`id` = `schedule_user`.`schedule_id`select * from `schedules` left JOIN (
    select `schedule_id`, count(attendance) as user_count from `schedule_user` where `attendance` = 1 group by `schedule_id`)
as `schedule_user` on `schedules`.`id` = `schedule_user`.`schedule_id`


Laravel SQLからクエリビルダーへの変換支援  も参考に。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/09/07 16:01 編集

    修正してみました。
    SQLについては正しく動作しているのですが、今まで取れていたカラム名でデータを取得できなくなりました。Undefined propertyとエラーが表示されています。

    キャンセル

  • 2019/09/07 18:54

    Laravel ってSQLのインラインビュー(今回のようにSELECTの中にSELECTがある) にきちんと対応できていないように思えます。
    CREATE VIEW VIEW1 AS SELECT ...
    でビューを作って、ビューを単純なテーブルのように取り込んでみては?

    キャンセル

0

$join->on('schedules.id', '=', 'schedule_user.schedule_id');})

ここを

$join->on('schedules.id', '=', \DB::raw('schedule_user.schedule_id'));})

ここを
でどうでしょうか

おそらく、第三引数がエスケープ処理されているので.を含めたテーブル名と認識されているのだと思います。
また、同名のカラム名がなければ、テーブル名が省略できる気がするので

$join->on('schedules.id', '=', 'schedule_id');})

でも行けるかも・・・?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/09/07 16:02

    確かにおっしゃる通りテーブル名は省略できますがエラー表示が変わることがなかったため、根本的な解決では無いかも?

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.37%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る