Начнем с вашего запроса
User::withTrashed()->groupBy('name')->havingRaw('count("name") >= 1')->get();
Это покажет все группы строк, количество которых равно 1 или больше. и это описание DISTINCT
.
Если вы хотите получить только повторяющиеся записи, вы должны получить группы, количество которых БОЛЬШЕ, чем 1.
Еще одна вещь, на которую следует обратить внимание, это то, что неагрегированный столбец будет выбран случайным образом. потому что, когда вы получаете имя и оно учитывается, например, если вы выбираете name,count(name), email
(электронная почта не входит в группу по предложению - не агрегируется), и 4 строки имеют одинаковое имя. так что вы увидите:
+--------+-------------+-------+
| Name | Count(Name) | Email |
+--------+-------------+-------+
| Joseph | 4 | X |
+--------+-------------+-------+
чего вы ожидаете вместо X
? какое из 4 писем? на самом деле, в SQLServer запрещено выбирать неагрегированный столбец, а другие базы данных просто выдадут вам случайный из подсчитываемых 3. см. этот ответ для более подробной информации, он очень хорошо объяснен: Все ли столбцы в списке SELECT имеют чтобы появиться в предложении GROUP BY
Итак, мы будем использовать having count(name) > 1
и выбрать только агрегированный столбец name
DB::from('users')->select('name')->groupBy('name')->havingRaw('count("name") > 1')->get();
Это должно дать вам (didn ' t проверьте это) это:
+--------+-------------+
| name | Count(name) |
+--------+-------------+
| Joseph | 4 |
+--------+-------------+
Это даст вам все имена, у которых есть 2 или более экземпляров. вы можете определить количество дубликатов в предложении имеющего. например, having count(name) = 3
даст вам все имена, которые имеют ровно 3 дубликата.
Итак, как получить второй дубликат? У меня вопрос:
Какой первый (оригинальный) дубликат? это тот, у которого самый старый created_at
или самый старый updated_at
? а может какое-то другое условие ?. по этой причине вам следует сделать еще один запрос с предложением order by
, чтобы получить дубликаты в наиболее удобном для вас порядке. например:
select * from `users` where `name` in (select `name` from users group by `name` having count(`name`) > 1) order by `id` asc
, что даст:
+----+-----------+----------------------+------+
| ID | Name | Email | Age |
+----+-----------+----------------------+------+
| 3 | Joseph | joseph410@mail.com | 21 |
| 5 | Joseph | jh.city89@mail.com | 24 |
| 8 | Joseph | psa.jos@mail.com | 34 |
| 9 | Joseph | joseph.la@mail.com | 28 |
+----+-----------+---------+------------+------+