2017-05-12 6 views
0

私はLaravelを新しくしました。Eloquentクエリをチェーン化しないようにするにはどうすればよいですか?

どのようにクエリが連鎖されるのを避けることができるのだろうか。

$visitRecords = VisitRecord::whereDate('visited_at', '=', Carbon::today()->toDateString()); 


$knockBounce = $visitRecords->where("bounce_zone", "1")->get()->count(); 


$approachBounce = $visitRecords->where("bounce_zone", "2")->get()->count(); 

これは私が書いたコードですが、これは私が期待しない結果になります...私が行ったクエリを確認し、これは私が得たものである

select * from `visit_records` where date(`visited_at`) = '2017-05-12' 

select * from `visit_records` where date(`visited_at`) = '2017-05-12' and `bounce_zone` = '1' 

select * from `visit_records` where date(`visited_at`) = '2017-05-12' and `bounce_zone` = '1' and `bounce_zone` = '2' 

結果。私は何を期待

...

select * from `visit_records` where date(`visited_at`) = '2017-05-12' 

select * from `visit_records` where date(`visited_at`) = '2017-05-12' and `bounce_zone` = '1' 

select * from `visit_records` where date(`visited_at`) = '2017-05-12' and `bounce_zone` = '2' 

私は雄弁な方法を経由して、代わりにこのクエリを行いたいです。あなたがここで私は

はさらに、約php clone

+0

チェック[この] (http://stackoverflow.com/a/27522556/6140684) - あなたはそれが連鎖していると確信していますか?それはしないでください –

+0

私はデバッグバーコンソールからこれらのSQLクエリを得た。 – hytm

答えて

2

あなたを読ん$visitRecordsオブジェクトをコピーするためにcloneを使用しているあなたは、コード

$visitRecords = VisitRecord::whereDate('visited_at', '=', Carbon::today()->toDateString()); 

$visitRecords1 = clone $visitRecords;  

$knockBounce = $visitRecords->where("bounce_zone", "1")->get()->count();  

$approachBounce = $visitRecords1->where("bounce_zone", "2")->get()->count(); 

下回ってみてください

objects二つの異なるを持っている必要があります

+2

- > get()を使わないで直接count()を使うべきです: –

1

単一のQueryBuilderオブジェクトをインスタンス化しました。

2番目のクエリに対して2番目のQueryBuilderオブジェクトを作成する必要があります。マシューさんのコメントごとに更新

//Only create one carbon object 
$date = Carbon::today()->toDateString() 

$knockBounce = VisitRecord::whereDate('visited_at', '=', $date)->where("bounce_zone", "1")->count(); 

$approachBounce = VisitRecord::whereDate('visited_at', '=', $date)->where("bounce_zone", "2")->count(); 

それが必要ではないですので、Laravelは、ボンネットの下に集約関数のためにとにかく->get()countminmaxavg)を実行します。

0

編集が代わりにのみ必要bounce_zone

を取るために、あなたは、コレクションを使用することができます。

$visitRecords = VisitRecord::whereDate('visited_at', '=', Carbon::today()->toDateString())->where("bounce_zone", "1")->orWhere("bounce_zone", "2")->get(); 


$knockBounce = $visitRecords->where("bounce_zone", "1")->count(); 


$approachBounce = $visitRecords->where("bounce_zone", "2")->count(); 

あなたが唯一のクエリを実行し、Laravelのすべての電源を使用:)

+0

クエリを一度実行しますが、何の費用がかかりますか?ビジネスロジックに依存しますが、処理しないデータの取得は避けてください。例えばすべてのレコード 'どこにbounce_zone(1,2)'が必要としない何百万もの行が存在する可能性がありますか? – Luke

+0

@lukeこのアプローチではより多くの計算が必要ですか? – hytm

+0

編集していただきありがとうございます! – hytm

関連する問題