mysql - 如何在 laravel 5.5 中只获取第二条重复记录?
问题描述
假设我有一个这样的用户表:
+----+-----------+----------------------+------+
| ID | Name | Email | Age |
+----+-----------+----------------------+------+
| 1 | John | john.doe1@mail.com | 24 |
| 2 | Josh | josh99@mail.com | 29 |
| 3 | Joseph | joseph410@mail.com | 21 |
| 4 | George | gge.48@mail.com | 28 |
| 5 | Joseph | jh.city89@mail.com | 24 |
| 6 | Kim | kimsd@mail.com | 32 |
| 7 | Bob | bob.s@mail.com | 38 |
| 8 | Joseph | psa.jos@mail.com | 34 |
| 9 | Joseph | joseph.la@mail.com | 28 |
| 10 | Jonathan | jonhan@mail.com | 22 |
+----+-----------+---------+------------+------+
实际上,数据库包含更多的数据,并且一些数据是重复的,有两条以上的记录。但关键是我只想获取包含“Joseph”名称的重复行的第一行和第二行,我该如何实现?到目前为止我的代码...
User::withTrashed()->groupBy('name')->havingRaw('count("name") >= 1')->get();
使用该代码,结果将检索:
+----+-----------+----------------------+------+
| ID | Name | Email | Age |
+----+-----------+----------------------+------+
| 1 | John | john.doe1@mail.com | 24 |
| 2 | Josh | josh99@mail.com | 29 |
| 3 | Joseph | joseph410@mail.com | 21 |
| 4 | George | gge.48@mail.com | 28 |
| 6 | Kim | kimsd@mail.com | 32 |
| 7 | Bob | bob.s@mail.com | 38 |
| 10 | Jonathan | jonhan@mail.com | 22 |
+----+-----------+---------+------------+------+
我使用此代码尝试获取第二个重复行:
User::withTrashed()->groupBy('name')->havingRaw('count("name") >= 2')->get();
结果仍然与上面提到的相同:
+----+-----------+----------------------+------+
| ID | Name | Email | Age |
+----+-----------+----------------------+------+
| 1 | John | john.doe1@mail.com | 24 |
| 2 | Josh | josh99@mail.com | 29 |
| 3 | Joseph | joseph410@mail.com | 21 |
| 4 | George | gge.48@mail.com | 28 |
| 6 | Kim | kimsd@mail.com | 32 |
| 7 | Bob | bob.s@mail.com | 38 |
| 10 | Jonathan | jonhan@mail.com | 22 |
+----+-----------+---------+------------+------+
我想要的结果是获取 ID 为“5”且名称为“Joseph”的记录,如下所示:
+----+-----------+----------------------+------+
| ID | Name | Email | Age |
+----+-----------+----------------------+------+
| 1 | John | john.doe1@mail.com | 24 |
| 2 | Josh | josh99@mail.com | 29 |
| 4 | George | gge.48@mail.com | 28 |
| 5 | Joseph | jh.city89@mail.com | 24 |
| 6 | Kim | kimsd@mail.com | 32 |
| 7 | Bob | bob.s@mail.com | 38 |
| 10 | Jonathan | jonhan@mail.com | 22 |
+----+-----------+---------+------------+------+
但似乎只检索到第一个重复行,我无法获得第二个重复行,有人可以给我建议吗?
解决方案
让我们从您的查询开始
User::withTrashed()->groupBy('name')->havingRaw('count("name") >= 1')->get();
这将显示计数等于或大于 1 的所有行组。这是 的描述DISTINCT
。
如果您只想获取重复记录,您应该获取计数大于 1 的组。
这里要注意的另一件事是,将随机选择一个非聚合列。因为当您获得一个名称并且它是计数时,例如,如果您选择name,count(name), email
(电子邮件不在 group by 子句中 - 未聚合),并且 4 行具有相同的名称。所以你会看到:
+--------+-------------+-------+
| Name | Count(Name) | Email |
+--------+-------------+-------+
| Joseph | 4 | X |
+--------+-------------+-------+
你期望什么而不是X
?4 封电子邮件中的哪一封?实际上,在 SQLServer 中,禁止选择非聚合列,其他数据库只会给你一个随机的 3 个。有关更多详细信息,请参阅此答案,它的解释很好:Do all columns in a SELECT list have to appear in一个 GROUP BY 子句
因此,我们将having count(name) > 1
仅使用并选择聚合列name
DB::from('users')->select('name')->groupBy('name')->havingRaw('count("name") > 1')->get();
这应该给你(没有测试)这个:
+--------+-------------+
| name | Count(name) |
+--------+-------------+
| Joseph | 4 |
+--------+-------------+
这将为您提供具有 2 个或更多实例的所有名称。您可以确定have子句中的重复数。例如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 |
+----+-----------+---------+------------+------+
推荐阅读
- lua - 从 luarocks 运行 busted - 'busted' 不被识别为内部或外部命令
- regex - Laravel 路由正则表达式以 @ 字符开头
- php - 如何使用 guzzle 6 发送 cookie?
- elasticsearch - Logstash 基于现有字段创建新字段
- r - R中的循环计算
- numbers - symfony 中的 Twig 格式化数字
- three.js - 退出 VR 模式时,移动设备上的 Aframe 分辨率下降
- rest - 如何为嵌套资源制作单独的 REST 控制器?弹簧靴
- c# - EntityFramework Core Update-Database 抛出异常“在程序集中找不到 DbContext”
- javascript - 新的输入类不能使用焦点和模糊事件