har*_*ryg 16 php laravel eloquent laravel-4
我有以下Eloquent查询(这是一个查询的简化版本,它由更多的wheres和orWheres 组成,因此显而易见的迂回方式 - 理论是重要的):
$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();
Run Code Online (Sandbox Code Playgroud)
你可以看到我pluck在我之前或之后发生的最早日期start_date.这会导致运行单独的查询以获取此日期,然后将其用作主查询中的参数.有没有一种方法可以将查询嵌入到一起形成子查询,从而只有1个数据库调用而不是2个?
编辑:
根据@ 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();
Run Code Online (Sandbox Code Playgroud)
这些orWhere块导致查询中的所有参数突然变得不加引号.例如WHEREprice_date >= 2009-09-07.当我删除该orWheres查询工作正常.为什么是这样?
Jar*_*zyk 24
这是你如何做一个子查询:
$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);
});
Run Code Online (Sandbox Code Playgroud)
不幸的是orWhere需要明确提供$operator,否则会引发错误,所以在你的情况下:
$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);
});
Run Code Online (Sandbox Code Playgroud)
编辑:你需要from在闭包中指定,否则它将无法构建正确的查询.
| 归档时间: |
|
| 查看次数: |
45017 次 |
| 最近记录: |