Получение различных записей с помощью построителя запросов и использования необработанных запросов отличается - PullRequest
0 голосов
/ 22 июня 2019

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?

Результат Tinker

>>> 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 ]

1 голос
/ 22 июня 2019

Метод distinct() не принимает никаких аргументов: https://laravel.com/api/5.6/Illuminate/Database/Query/Builder.html#method_distinct. Ваш рукописный запрос SQL считает различные status_audits.video_id s, но ваш код построителя запросов считает различные строки.

Вы можетепередайте имя столбца методу 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')
0 голосов
/ 22 июня 2019

Ваши литералы даты в звонках на 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);
...