我在我的Laravel项目中使用了以下Raw查询。
$statisticsInRangeDate = $myModel->selectRaw(
"floor(datediff(created_at, '{$dateInfo['currentRangeDate']}')".
" / {$dateInfo['daysRange']}) * {$dateInfo['daysRange']} AS diff_days_range, count(*) as total_clicks, ".
'min(created_at) ,max(created_at)'
)
->groupByRaw('diff_days_range')
->orderByRaw('diff_days_range DESC')
->get();
原始查询为:
select
floor(datediff(created_at, '2023-04-04') / 3) * 3 AS diff_days_range,
count(*) as total_install,
min(created_at),
max(created_at)
from sdk_clicks
where sdk_clicks.application_id = 1
and sdk_clicks.application_id is not null
and created_at >= '2023-04-01'
and created_at < '2023-04-07'
and sdk_clicks.deleted_at is null
group by diff_days_range
order by diff_days_range
项目的数据库是mysql,我得到了必要的输出,但是当我运行phpunit测试时,我得到了以下错误,该测试使用了sqlite内存数据库以提高速度。
Illuminate\Database\QueryException:SQLSTATE[HY000]:一般错误:1无此功能:datediff(SQL:选择楼层...
我知道这个函数在sqlite中不存在,应该使用julianday('now') - julianday(DateCreated)
来计算时间差,但我正在寻找通过检测数据库类型和使用适当函数来自动解决这个问题的最佳解决方案。
注意:由于高速测试的需要,我想使用内存和sqlite数据库
2条答案
按热度按时间xpszyzbs1#
PHP提供了在sqlite中创建用户定义函数的能力。这是使用
PDO::sqliteCreateFunction()
function完成的。基本上,您在sqlite中定义了一个函数,它将调用您提供的PHP代码。
你的代码看起来像这样:
在执行查询之前将其添加到测试套件中的某个地方,您应该会很好。
1dkrff032#
考虑到使用Macro in laravel的可能性,它允许我向
Illuminate\Database\Eloquent\Builder
添加新功能。在AppServiceProvider.php中,我创建了宏rangeDateDiff():
然后在Eloquent模型中使用这个新函数globaly:
这种方法的优点是更干净,最重要的是,如果项目中需要使用另一种类型的数据库,代码更易于维护。