ich folgende Eloquent Abfrage habe (Dies ist eine vereinfachte Version einer Abfrage, das gehe über diesen von mehr where
s und orWhere
s daher den scheinbaren Umweg besteht - ist die Theorie, was wichtig ist):Wie erstellt man eine Unterabfrage mit Laravel Eloquent?
$start_date = //some date;
$prices = BenchmarkPrice::select('price_date', 'price')
->orderBy('price_date', 'ASC')
->where('ticker', $this->ticker)
->where(function($q) use ($start_date) {
// some wheres...
$q->orWhere(function($q2) use ($start_date){
$dateToCompare = BenchmarkPrice::select(DB::raw('min(price_date) as min_date'))
->where('price_date', '>=', $start_date)
->where('ticker', $this->ticker)
->pluck('min_date');
$q2->where('price_date', $dateToCompare);
});
})
->get();
Wie Sie sehen können, bin ich pluck
das früheste Datum, das auf oder nach meiner start_date
auftritt. Dies führt dazu, dass eine separate Abfrage ausgeführt wird, um dieses Datum zu erhalten, das dann als Parameter in der Hauptabfrage verwendet wird. Gibt es eine Möglichkeit eloquent, die Abfragen zu einer Unterabfrage zusammenzufassen und somit nur 1 Datenbankanruf statt 2?
Edit:
Wie pro @ Jareks Antwort auf diese meine Frage ist:
$prices = BenchmarkPrice::select('price_date', 'price')
->orderBy('price_date', 'ASC')
->where('ticker', $this->ticker)
->where(function($q) use ($start_date, $end_date, $last_day) {
if ($start_date) $q->where('price_date' ,'>=', $start_date);
if ($end_date) $q->where('price_date' ,'<=', $end_date);
if ($last_day) $q->where('price_date', DB::raw('LAST_DAY(price_date)'));
if ($start_date) $q->orWhere('price_date', '=', function($d) use ($start_date) {
// Get the earliest date on of after the start date
$d->selectRaw('min(price_date)')
->where('price_date', '>=', $start_date)
->where('ticker', $this->ticker);
});
if ($end_date) $q->orWhere('price_date', '=', function($d) use ($end_date) {
// Get the latest date on or before the end date
$d->selectRaw('max(price_date)')
->where('price_date', '<=', $end_date)
->where('ticker', $this->ticker);
});
});
$this->prices = $prices->remember($_ENV['LONG_CACHE_TIME'])->get();
Die orWhere
Blöcke verursachen alle Parameter in der Abfrage plötzlich nicht notierte werden. Z.B. WHERE
price_date >= 2009-09-07
. Wenn ich die orWheres
entferne, funktioniert die Abfrage gut. Warum ist das? Diese
Plus 1 - Dies ist die richtige Antwort. Ich werde meine löschen, sobald das OP diese Antwort akzeptiert. –
Sieht wieder gut aus, außer die Bindung stimmt nicht ganz. Ich finde, dass der Parameter $ this -> ticker in die Abfrage ohne Anführungszeichen eingegeben wird, was zu einem Fehler führt. Z.B. '... UND ticker = ukc0tr01 INDEX) ...' – harryg
Das gleiche geschieht auch für das Datum: 'WHERE price_date <= 2014-07-31'. Warum keine Zitate um das Datum? – harryg