Laravel Eloquent захватывает дубликаты (2 или более результатов)

Итак, у меня есть следующий запрос, который работает:

Expense::select('amount', 'date', DB::raw('COUNT(*) as `count`'))
        ->groupBy('amount', 'date')
        ->havingRaw('COUNT(*) > 1')
        ->get();

Это нужно для того, чтобы захватить все expenses, которые являются потенциальными дубликатами (такая же сумма и та же дата). Однако я хочу схватить все, а не только amount и date. Не работает следующее:

    return Expense::select('name', 'amount', 'date', DB::raw('COUNT(*) as `count`'))
        ->groupBy('amount', 'date')
        ->havingRaw('COUNT(*) > 1')
        ->get();

Это даст мне эту ошибку:

SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #1 of the SELECT list is not in the GROUP BY clause and contains a nonaggregated column

У меня есть еще много полей для Expense, которые я хочу перечислить, на мой взгляд, самое главное, конечно, имя, но также и слаг, чтобы я мог ссылаться на каждый потенциальный дубликат и т. д.

Также вторая "проблема", но не самая важная, заключается в том, что при указанном выше запросе все расходы возвращаются одной коллекцией. Например, они не сгруппированы по дате.

Наиболее желательным было бы иметь примерно такие результаты. Все потенциальные дубликаты должны быть сгруппированы по дате, чтобы я мог сделать что-то вроде этого, на мой взгляд:

@foreach($duplicates as $date => $expenses)

    @foreach($expenses as $expense)

    {{ $date }}

    // List all expenses for that date.. etc.

Вопрос 1: Как сделать так, чтобы приведенный выше запрос работал со всеми полями базы данных, а не только с date и amount?

Вопрос 2: Как я могу получить потенциальные дубликаты и сгруппировать их по дате, чтобы я мог перебирать даты и расходы, как в приведенном выше примере?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
0
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Всегда правильно обрабатывайте столбец при группировке

э.и. вы можете указать все поля, которые вы хотите выбрать в groupBy

// database query
$expenses = Expense::select(['amount', 'date', 'name', 'slug'])
                    ->selectRaw('count(*) AS count')
                    ->havingRaw('count > 1')
                    ->groupBy(['amount', 'date', 'name', 'slug'])
                    ->get();

// Another date grouping done in collection
return $expenses->groupBy('date');

или что-то вроде расчесывания столбцов, принадлежащих к желаемой группе

return Expense::select('date')
    ->selectRaw('group_concat(name) as names') // comma separated names belongs to the group 
    ->selectRaw('group_concat(amount) as amounts') // comma separated amounts belongs to the group 
    ->selectRaw('group_concat(slug) as slugs')// comma separated slugs belongs to the group 
    ->selectRaw('count(*) AS count')
    ->havingRaw('count > 1')
    ->groupBy('date')
    ->get();

РЕДАКТИРОВАТЬ

Если вы хотите сгруппировать их только по дате и при этом иметь фактические повторяющиеся строки, вы можете просто добавить еще один оператор выбора для подсчета дубликатов даты, не группируя их по дате в своем запросе, и выполнить группировку даты в коллекции.

э.и.

$expenses  = Expense::select( ['amount', 'date', 'name', 'slug'] )
    ->selectRaw('(SELECT COUNT(date) FROM expenses t1 WHERE t1.date = expenses.date ) as duplicates')
    ->havingRaw('duplicates > 1')
    ->get();

return $expenses->groupBy('date');

Затем в выходных данных должен быть еще один столбец duplicates, в котором указано количество дубликатов каждой даты, а также все строки для повторяющихся дат.

Спасибо! Но теперь он также будет группироваться по имени и слагу, а мне нужно, чтобы он был сгруппирован только по дате.

Hardist 07.02.2023 17:53

Проведя еще несколько исследований, сформулировать такой запрос не так просто, однако я получу то, что хочу, другим способом. Вы все же ответили на мой второй вопрос, который я должен был знать сам, лол, но я все равно приму ваш ответ, спасибо!

Hardist 07.02.2023 19:30

@Hardist, я отредактировал свой ответ, думаю, это то, что тебе нужно.

silver 08.02.2023 03:38

Большое спасибо, это имеет смысл, и я попробую это позже, мне очень помогает!

Hardist 08.02.2023 09:30

Работает просто отлично, я изменил только это: WHERE t1.date = expenses.date AND t1.amount = expenses.amount чтобы убедиться, что я получаю только дубликаты, где дата и сумма совпадают. Но, кажется, работает отлично, большое спасибо

Hardist 08.02.2023 09:40

Другие вопросы по теме