Ho la seguente domanda Eloquente (Questa è una versione semplificata di una query che consiste di più where
s e orWhere
s da qui il modo indiretto apparente di andare su questo - la teoria è quello che è importante):Come creare una sottoquery usando 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();
Come si può vedere I pluck
la prima data che si verifica su o dopo il mio start_date
. Ciò comporta l'esecuzione di una query separata per ottenere questa data che viene quindi utilizzata come parametro nella query principale. C'è un modo eloquente per incorporare le query insieme per formare una sottoquery e quindi solo 1 chiamata al database piuttosto che 2?
Edit:
Come da @ risposta di Jarek questa è la mia domanda:
$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();
I orWhere
blocchi stanno causando tutti i parametri della query di diventare improvvisamente non quotate. Per esempio. WHERE
price_date >= 2009-09-07
. Quando rimuovo lo orWheres
, la query funziona correttamente. Perchè è questo?
Più 1 - Questa è la risposta corretta. Cancellerò il mio non appena l'OP accetta questa risposta. –
Anche in questo caso sembra buono, tranne che il binding non è corretto. Trovo che il parametro '$ this-> ticker' sia inserito nella query non quotata risultante in un errore. Per esempio. '... AND ticker = ukc0tr01 INDEX) ...' – harryg
Lo stesso vale anche per la data: 'WHERE price_date <= 2014-07-31'. Perché nessuna citazione intorno alla data? – harryg