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

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

ただいまの
回答率

88.92%

Laravelのサブクエリの書き方、使い方を教えてほしいです。

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 1,672

harusyoui

score 27

前提・実現したいこと

select sum(total_amount) 
from( 
SELECT * FROM sales_data 
where date(deposit_date) = '2018-12-09' 
group by order_id, cancel_id, shop_id 
) as date_sales

というSQL文をサブクエリを使いLaravelのコントローラで再現しようと
しているのですが、サブクエリをSelectする際にエラーが出てしまいます。
上手くいくやり方を教えていただけたら幸いです。

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

BadMethodCallException
Method select does not exist.

該当のソースコード

$sub_query = Sales_data::whereDate('deposit_date', '=', '2018-12-09')
           ->GROUPBY('order_id', 'cancel_id', 'shop_id')
           ->get();

$total_sales = $sub_query::select('SUM(total_amount)')
             ->get();
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • m.ts10806

    2018/12/12 13:07

    前も指摘したかもしれませんが、必要なところを省略されると情報の正確性が失われて回答に反映できません。つまり的確な回答は得られず問題解決までの時間が2人分浪費されることになります。基本的にそのまま提示してください。

    キャンセル

  • m.ts10806

    2018/12/12 13:08

    今回で言えば「CREATE文とINSERT文」だけがあればいいのでコメント部分(-- XXX)とかダンプの情報がどうとかは一切不要なわけですし。

    キャンセル

  • m.ts10806

    2018/12/13 10:03

    色々書いているのでどの程度理解されたのかは知りたいですね。同程度の質問繰り返されても困りますし誰も回答しなくなります。 https://teratail.com/help/question-tips#questionTips4-2

    キャンセル

回答 2

+1

インラインビューにする必要があるんですか?

select sum(total_amount) as total_amount
FROM sales_data 
where date(deposit_date) = '2018-12-09' 


インラインビューにしたければVIEWにしてLaravelの方をシンプルにするとか?

CREATE VIEW VIEW_NAME1 AS
select sum(total_amount) as total_amount
...

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/12/12 12:13

    普通にgroupbyしてsumすると各行のsumしか出てく来なくで、
    groupbyした上での全ての行のsumを求めたいんですよ。

    キャンセル

  • 2018/12/12 12:17

    上記のSQLで全ての行のsumが1行表示されませんか?

    キャンセル

  • 2018/12/12 13:14 編集

    確かに前の質問ではあえて突っ込まなかったんですけど、そもそもGroup Byする必要あるのかなと思います。実データ提供されないと分からないですが、単にwhereで絞ってsumしても結果同じになりそうですし。

    キャンセル

checkベストアンサー

0

Method select does not exist.

selectというメソッドは存在しませんというエラーですね。
リファレンスから、get()はIlluminate\Support\Collectionを返します。

getメソッドは、PHPのstdClassオブジェクトのインスタンスを結果として含む、Illuminate\Support\Collectionを返します。各カラムの値は、オブジェクトのプロパティとしてアクセスできます。

コードを追ってみれば分かりますが、下記の通り、Illuminate\Support\Collectionにはselect()はありません。そのためのエラーです。

/**

  • @property-read HigherOrderCollectionProxy $average
  • @property-read HigherOrderCollectionProxy $avg
  • @property-read HigherOrderCollectionProxy $contains
  • @property-read HigherOrderCollectionProxy $each
  • @property-read HigherOrderCollectionProxy $every
  • @property-read HigherOrderCollectionProxy $filter
  • @property-read HigherOrderCollectionProxy $first
  • @property-read HigherOrderCollectionProxy $flatMap
  • @property-read HigherOrderCollectionProxy $groupBy
  • @property-read HigherOrderCollectionProxy $keyBy
  • @property-read HigherOrderCollectionProxy $map
  • @property-read HigherOrderCollectionProxy $max
  • @property-read HigherOrderCollectionProxy $min
  • @property-read HigherOrderCollectionProxy $partition
  • @property-read HigherOrderCollectionProxy $reject
  • @property-read HigherOrderCollectionProxy $sortBy
  • @property-read HigherOrderCollectionProxy $sortByDesc
  • @property-read HigherOrderCollectionProxy $sum
  • @property-read HigherOrderCollectionProxy $unique
  •  
  • Class Collection
    */

ただ、見ての通りsumはあるので下記のようにすれば良いのでは。

※データは簡易に作った下記で確認

DROP TABLE IF EXISTS sales_data;
CREATE TABLE sales_data (
    id integer NOT NULL, 
    name varchar(10) NOT NULL, 
    order_id integer NOT NULL, 
    total integer NOT NULL, 
    date date NOT NULL, 
    CONSTRAINT sales_data_pkey PRIMARY KEY (id, order_id)
  );

insert into sales_data (id, name, order_id, total, date) 
values 
  (
    '1', 'test', '1', '10', '2018-10-09'
  );
insert into sales_data (id, name, order_id, total, date) 
values 
  (
    '2', 'test', '2', '9', '2018-10-09'
  );
insert into sales_data (id, name, order_id, total, date) 
values 
  (
    '2', 'test', '3', '8', '2018-10-09'
  );
insert into sales_data (id, name, order_id, total, date) 
values 
  (
    '3', 'test', '4', '2', '2018-10-09'
  );
insert into sales_data (id, name, order_id, total, date) 
values 
  (
    '2', 'test', '5', '3', '2018-10-10'
  );
insert into sales_data (id, name, order_id, total, date) 
values 
  (
    '2', 'test', '6', '4', '2018-10-08'
  );
$sub = DB::table("sales_data")->whereDate("date","=","2018-10-09")
           ->groupBy('order_id','id')
           ->get();
dd($sub->sum("total"));
//29


※こっそりなおしましたが、正確にはGROUPBYではなくgroupByです。メソッド名は大文字小文字大別しないPHPですが、正確に記載されたほうがトラブル少なくて済みます。

ただ、結果は(文字列か数字かはともかく)下記と同じです。

dd(DB::table("sales_data")->whereDate("date","=","2018-10-09")->sum("total"));
//"29"

group by 本当に必要?
いう疑問はぬぐえません。
欲しい結果がこれで良いのでしたらgroup byせずにsumした方が効率的にも速度的にもいいですし、
そうでないなら「こういうデータでこういう結果が欲しい」というのを具体的に例示してください。

蛇足:
sales_dataというデータですが、shop_flgとかshop_nameって必要なんでしょうか。
shopのマスターテーブルがあるならそちらから引っ張ってくるようにすべきと。
「そのときの店舗名」というなら仕方がないかもしれませんが、
そうであったとしてもそこまで頻繁にかわるものでもないでしょうし、もっと効率的なデータの持ち方があるように思います。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/12/13 10:25

    $sub_query = sales_data::select('*')
    ->where("deposit_date", "like", $date."%")
    ->groupBy('order_id', 'cancel_id', 'shop_id')
    ->get();

    $total_sales = $data_sales->where('goods_order_type', '=', 1)->sum('total_amount');

    とサブクエリを書いたら上手くいきました、ありがとうございます。

    キャンセル

  • 2018/12/13 10:28

    急に出てきている $data_salesは何でしょうか?
    それと何度か突っ込まれてますがgroupBy本当に必要なんでしょうか。
    groupByなしで単にsumしても結果は同じになりませんか?

    キャンセル

  • 2018/12/13 10:41

    変わったデータを使ってまして、
    groupbyを使わないと望んでいる結果の値よりも
    多くなってしまうんですよ。

    キャンセル

  • 2018/12/13 10:50

    それを知ってるのは質問者さんだけですよね。
    それが分かる情報を提示しないと誰もあなたが欲しい回答はできませんよ。
    逆の立場になってみてください。

    キャンセル

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

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

関連した質問

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