根据一列或两列选择所有重复的行?

use*_*692 5 mysql duplicates

我有一个contacts用字段命名的表

+-----+------------+-----------+
| id  | first_name | last_name |
+-----+------------+-----------+
Run Code Online (Sandbox Code Playgroud)

我想基于first_name和(/或)显示所有重复项last_name,例如:

+----+------------+-----------+
| id | first_name | last_name |
+----+------------+-----------+
|  1 | mukta      | chourishi |
|  2 | mukta      | chourishi |
|  3 | mukta      | john      |
|  4 | carl       | thomas    |
+----+------------+-----------+
Run Code Online (Sandbox Code Playgroud)

如果搜索first_name它应该返回:

+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
+----+
Run Code Online (Sandbox Code Playgroud)

但如果在两者上搜索first_namelast_name应该返回:

+----+
| id |
+----+
|  1 |
|  2 |
+----+
Run Code Online (Sandbox Code Playgroud)

Gri*_*han 6

实现结果的一种方法是使用嵌套查询和having子句:在内部查询中选择那些计数多于一的那些,并在外部查询中选择id:

检查以下示例的单列选择标准:

创建表格:

CREATE TABLE `person` (
    `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
    `first` varchar(120) NOT NULL,
    `last` varchar(120) NOT NULL
);
Run Code Online (Sandbox Code Playgroud)

插入元组:

INSERT INTO `person` ( `first`, `last`) VALUES
("mukta", "chourishi"),
("mukta", "chourishi"),
("mukta", "john"),
("carl", "thomas" );
Run Code Online (Sandbox Code Playgroud)

您需要的结果:

mysql> SELECT  `id` 
    -> FROM `person` 
    -> WHERE `first`=(SELECT `first` FROM `person` HAVING COUNT(`first`) > 1);
+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
+----+
3 rows in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

[回答]

但好像您的选择标准是基于多个列,那么您可以使用JOIN.

为了解释它,我正在编写一个选择查询,该查询创建一个将在JOIN中用作第二个操作数表的中间表.

查询是选择所有拳头名称和列与其他一些行重复:
例如选择其中的行firstlast名称重复

mysql> SELECT `first`, `last`,  count(*)  as rows 
    -> FROM `person` 
    -> GROUP BY `first`, `last` 
    -> HAVING count(rows) > 1;
+-------+-----------+------+
| first | last      | rows |
+-------+-----------+------+
| mukta | chourishi |    2 |
+-------+-----------+------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

所以你只有一对firstlast命名那些重复(或与其他一些行重复).

现在,问题是:如何选择id这一行?使用加入!如下:

mysql> SELECT  p1.`id`
    -> FROM `person` as p1
    -> INNER JOIN (
    ->     SELECT `first`, `last`,  count(*)  as rows
    ->     FROM `person` 
    ->     GROUP BY `first`, `last` 
    ->     HAVING count(rows) > 1) as p
    -> WHERE p.`first` = p1.`first` and p.`last` = p1.`last`;  
+----+
| id |
+----+
|  1 |
|  2 |
+----+
2 rows in set (0.06 sec)
Run Code Online (Sandbox Code Playgroud)

您可以根据需要选择多列,例如单列,如果您想使用连接,则删除姓氏.