2014-11-21 6 views
12

나는 다음과 같은 웅변 질의했다 (이 때문에 더 where들과 orWhere의의의 이것에 대해가는 명백한 로터리 방식으로 구성되어 쿼리의 단순화 된 버전입니다 - 이론은 중요한 것입니다) :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(); 

보시다시피 pluckstart_date 또는 그 이후에 발생한 가장 빠른 날짜. 그 결과 별도의 쿼리가 실행되어이 날짜를 가져 와서 기본 쿼리의 매개 변수로 사용됩니다. 하위 쿼리를 구성하기 위해 쿼리를 함께 포함시키는 방법이 있습니까? 그렇기 때문에 2가 아닌 1 개의 데이터베이스 호출 만 구성 할 수 있습니까?

편집 :이 내 쿼리입니다

Jarek의 대답 @를 당으로 :

$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(); 

orWhere 블록이 쿼리의 모든 매개 변수가 갑자기 인용 부호가되기 위해 원인이된다. 예 : WHERE price_date >= 2009-09-07. orWheres을 제거하면 쿼리가 정상적으로 작동합니다. 왜 이런거야?

답변

16

이것은 하위 쿼리 할 방법은 다음과 같습니다 그렇지 않으면, 오류를 제기합니다, 불행하게도 orWhere 명시 적으로 $operator를 제공 필요

$q->where('price_date', function($q) use ($start_date) 
{ 
    $q->from('benchmarks_table_name') 
    ->selectRaw('min(price_date)') 
    ->where('price_date', '>=', $start_date) 
    ->where('ticker', $this->ticker); 
}); 

를 귀하의 경우 너무 :

$q->orWhere('price_date', '=', function($q) use ($start_date) 
{ 
    $q->from('benchmarks_table_name') 
    ->selectRaw('min(price_date)') 
    ->where('price_date', '>=', $start_date) 
    ->where('ticker', $this->ticker); 
}); 

편집 : 당신은 실제로 폐쇄에 from을 지정해야합니다, 그렇지 않으면 그것은 정확한 쿼리를 작성하지 않습니다.

+3

플러스 1 - 정답입니다. OP가이 대답을 수락하자마자 광산을 삭제합니다. –

+0

바인딩이 옳지 않다는 점을 제외하고 다시 한 번 좋아 보인다. '$ this-> ticker' 매개 변수가 따옴표로 묶이지 않은 쿼리에 입력되어 오류가 발생합니다. 예 : '... AND ticker = ukc0tr01 INDEX) ... ' – harryg

+0

날짜도'WHERE price_date <= 2014-07-31'과 동일합니다. 왜 날짜를 따옴표없이? – harryg

관련 문제