使用查询生成器和使用原始查询获取不同的记录laravel有所不同

时间:2019-06-22 12:41:38

标签: laravel eloquent laravel-query-builder

Laravel 5.6.29 PHP 7.3.5

App\StatusAudit::where('user_id', 39)->where('new_status', 4)->whereBetween(
'created_at', [\Carbon\Carbon::parse('22-05-2019')->toDateString(), \Carbon\Carbon::parse('22-06
-2019')->toDateString()])->distinct()->count()

给出结果31,status_audits.id不同,所以31,正确,但是->distinct('video_id')给出31很有趣!并使用groupBy给我1。

SELECT COUNT( DISTINCT status_audits.video_id) FROM status_audits WHERE user_id = 39 AND new_status = 4 AND DATE(created_at) BETWEEN "2019-05-22" AND "2019-06-22"

捐出30

为什么结果30和31有差异?

修补程序结果

>>> App\StatusAudit::where('user_id', 39)->where('new_status', 4)->whereBetween(
'created_at', [\Carbon\Carbon::parse('22-05-2019')->toDateString(), \Carbon\Carb
on::parse('22-06-2019')->toDateString()])->distinct('video_id')->count()
=> 31
>>> App\StatusAudit::where('user_id', 39)->where('new_status', 4)->whereBetween(
'created_at', [\Carbon\Carbon::createFromFormat('d-m-Y', '22-05-2019'), \Carbon\
Carbon::createFromFormat('d-m-Y', '22-06-2019')])->distinct('video_id')->count()
=> 28

>>> App\StatusAudit::where('user_id', 39)->where('new_status', 4)->whereBetween(
'created_at', [\Carbon\Carbon::createFromFormat('d-m-Y', '22-05-2019')->toDateSt
ring(), \Carbon\Carbon::createFromFormat('d-m-Y', '22-06-2019')->toDateString()]
)->distinct('video_id')->count()
=> 31

GroupBy结果

$ php artisan tinker
Psy Shell v0.9.9 (PHP 7.3.5 — cli) by Justin Hileman
>>> App\StatusAudit::where('user_id', 39)->where('new_status', 4)->whereBetween(
'created_at', [\Carbon\Carbon::createFromFormat('d-m-Y', '22-05-2019')->toDateSt
ring(), \Carbon\Carbon::createFromFormat('d-m-Y', '22-06-2019')->toDateString()]
)->groupBy('video_id')->count()
=> 1

更新 获取收集并计算唯一记录的效率不高,但这是一种解决方法

>>> App\StatusAudit::where('user_id', 39)->where('new_status', 4)->whereBetween(
    'created_at', [\Carbon\Carbon::parse('22-05-2019')->toDateString(), \Carbon\Carb
    on::parse('22-06-2019')->toDateString()])->get()->unique('video_id')->count()
    => 30

另一个解决方法是

>>> App\StatusAudit::where('user_id', 39)->where('new_status', 4)->whereBetween(
'created_at', [\Carbon\Carbon::createFromFormat('d-m-Y', '22-05-2019')->toDateSt
ring(), \Carbon\Carbon::createFromFormat('d-m-Y', '22-06-2019')->toDateString()]
)->distinct()->pluck('video_id')->count()

2 个答案:

答案 0 :(得分:1)

distinct()方法不接受任何参数:https://laravel.com/api/5.6/Illuminate/Database/Query/Builder.html#method_distinct。您的手写SQL查询正在计算不同的status_audits.video_id,但是您的查询构建器代码在计算不同的行。

您可以将列名传递给count()方法,以仅计算与该列不同的值。

App\StatusAudit::where('user_id', 39)->where('new_status', 4)->whereBetween(
'created_at', [\Carbon\Carbon::parse('22-05-2019')->toDateString(), \Carbon\Carbon::parse('22-06
-2019')->toDateString()])->distinct()->count('video_id')

答案 1 :(得分:0)

您对Carbon::parse的调用中的日期字面值使我望而却步。尝试使用ISO格式:

App\StatusAudit::where('user_id', 39)
    ->where('new_status', 4)
    ->whereBetween('created_at', [\Carbon\Carbon::parse('2019-05-22'),
                       \Carbon\Carbon::parse('2019-06-22')])
    ->distinct()
    ->count();

如果您想对日期字符串使用dd/mm/YYYY格式,那么您可能必须使用类似以下的内容:

$date = Carbon\Carbon::createFromFormat('d-m-Y', '22-05-2019);