我正在使用Illuminate数据库查询构建器进行查询。 当我使用查询时,结果不像我预期的那样。 当使用来自querylog的查询直接使用mysql cli时,我得到了预期的结果。
使用查询构建器:
->table('CompanyTools')
->select(
'CompanyTools.toolId',
$db->raw('COUNT(CompanyTools.toolId) as count')
)
->whereYear('CompanyTools.date', '>', 'YEAR(DATE_SUB(CURDATE(), INTERVAL 1 YEAR))')
->groupBy('CompanyTools.toolId')
->orderBy('count', 'DESC')
->take(1)
->get();
结果:
Array ( [toolId] => 88 [count] => 55 )
使用mysql cli:
select `CompanyTools`.`toolId`, COUNT(CompanyTools.toolId) as count from `CompanyTools`
where year(`CompanyTools`.`date`) > YEAR(DATE_SUB(CURDATE(), INTERVAL 1 YEAR))
group by `CompanyTools`.`toolId`
order by `count` desc
limit 1
结果:
ToolId: 88
count: 17
如果我(在查询构建器中)将'YEAR(DATE_SUB(CURDATE(), INTERVAL 1 YEAR))'
替换为2013
,我会得到:
Array ( [toolId] => 88 [count] => 17 )
以某种方式,date_sub被忽略,因此结果包括所有年份
我试着用->whereYear('CompanyTools.date', '>', $db->raw('YEAR(DATE_SUB(CURDATE(), INTERVAL 1 YEAR))'))
没有运气。
我想我可以使用php来计算所需的年份,但我宁愿让查询正确。
提前谢谢
/ j
更新
更换
->whereYear('CompanyTools.date', '>', 'YEAR(DATE_SUB(CURDATE(), INTERVAL 1 YEAR))')
与
->where($db->raw('YEAR(CompanyTools.date)'), '>', $db->raw('YEAR(DATE_SUB(CURDATE(), INTERVAL 1 YEAR))'))
解决它。不够聪明,不知道为什么,但也许whereYear函数应该被不同地使用
答案 0 :(得分:2)
正如您已经发现的那样使用
->where($db->raw('YEAR(CompanyTools.date)'), '>', $db->raw('YEAR(DATE_SUB(CURDATE(), INTERVAL 1 YEAR))'))
或者
->whereRaw('YEAR(CompanyTools.date) > YEAR(DATE_SUB(CURDATE(), INTERVAL 1 YEAR))')
解决了这个问题。
对于每个“普通”查询,Laravel使用绑定。显然,像YEAR(DATE_SUB(CURDATE(), INTERVAL 1 YEAR))
这样的SQL函数不适用于绑定。
通常,您可以使用DB::raw('YEAR(DATE_SUB(CURDATE(), INTERVAL 1 YEAR))')
,Laravel不会使用绑定。例如,在where()
中(表达式是类DB::raw()
返回)
if ( ! $value instanceof Expression)
{
$this->addBinding($value, 'where');
}
但是whereYear()
函数没有做这样的事情。它使用addDateBasedWhere()
并只添加一个绑定,而不检查该值是否为Expression
的实例
protected function addDateBasedWhere($type, $column, $operator, $value, $boolean = 'and')
{
$this->wheres[] = compact('column', 'type', 'boolean', 'operator', 'value');
$this->addBinding($value, 'where');
return $this;
}
这意味着查询将使用绑定,因此根本不执行日期计算。