删除MySQL表中的相同项

删除MySQL表中的相同项,mysql,sql,Mysql,Sql,我是MySQL的初学者。在这里,我刚刚创建了一个表 CREATE TABLE Student ( Rollno int, LastName varchar(255), FirstName varchar(255), Gpa float, ); 创建表之后,我在下面的查询的帮助下添加了这些值 USE persons; INSERT INTO student VALUES (1, 'Aa', 'A', 8.5), (2, 'Bb', 'B', 8.6), (3

我是MySQL的初学者。在这里,我刚刚创建了一个表

CREATE TABLE Student (
    Rollno int,
    LastName varchar(255),
    FirstName varchar(255),
    Gpa float,
);
创建表之后,我在下面的查询的帮助下添加了这些值

USE persons;
INSERT INTO student
VALUES
 (1, 'Aa', 'A', 8.5),
 (2, 'Bb', 'B', 8.6),
 (3, 'Cc', 'C', 8.7),
 (4, 'Dd', 'D', 8.4);
我刚刚运行了两次上述查询,结果有两个条目,如下所示

所以我只想删除重复的条目,结果数据库应该如下所示

虽然我进行了搜索和尝试,但我没有像本文中提到的
id
这样的唯一值

我在代码的帮助下再次尝试,如下所示

WITH cte AS (
    SELECT
        Rollno,
        LastName,
        FirstName,
        Gpa,
        ROW_NUMBER() OVER (
            PARTITION BY
                Rollno
            ORDER BY
                Rollno
        )RN
     FROM
        persons.student
)
DELETE FROM cte
WHERE RN > 1;
但是上面的错误说明

错误代码:1288。删除的目标表cte不可更新


因此,我只想要一个最佳解决方案,在表中有单个条目。

下面是我使用您的数据测试的解决方案。感谢您提供了一个完整且易于测试的案例

mysql> alter table student add column id int auto_increment primary key first;
Query OK, 0 rows affected (0.08 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> select * from student;
+----+--------+----------+-----------+------+
| id | Rollno | LastName | FirstName | Gpa  |
+----+--------+----------+-----------+------+
|  1 |      1 | Aa       | A         |  8.5 |
|  2 |      2 | Bb       | B         |  8.6 |
|  3 |      3 | Cc       | C         |  8.7 |
|  4 |      4 | Dd       | D         |  8.4 |
|  5 |      1 | Aa       | A         |  8.5 |
|  6 |      2 | Bb       | B         |  8.6 |
|  7 |      3 | Cc       | C         |  8.7 |
|  8 |      4 | Dd       | D         |  8.4 |
+----+--------+----------+-----------+------+
8 rows in set (0.00 sec)

mysql> delete s1 from student as s1 join student as s2 on s1.rollno=s2.rollno and s1.id > s2.id;
Query OK, 4 rows affected (0.03 sec)

mysql> select * from student;
+----+--------+----------+-----------+------+
| id | Rollno | LastName | FirstName | Gpa  |
+----+--------+----------+-----------+------+
|  1 |      1 | Aa       | A         |  8.5 |
|  2 |      2 | Bb       | B         |  8.6 |
|  3 |      3 | Cc       | C         |  8.7 |
|  4 |      4 | Dd       | D         |  8.4 |
+----+--------+----------+-----------+------+
4 rows in set (0.00 sec)

请回复您的评论:

此查询中的
s1
s2
通常被称为“表别名”,但您应该将它们更像行别名。它们一次引用一行,因此您可以比较相应行中的值

假设有两行,如下所示:

+----+--------+----------+-----------+------+
| id | Rollno | LastName | FirstName | Gpa  |
+----+--------+----------+-----------+------+
|  1 |      1 | Aa       | A         |  8.5 |
|  5 |      1 | Aa       | A         |  8.5 |
哪一行可以用
s1
表示,哪一行可以是
s2
,这样连接条件才是真的

这两行具有相同的Rollno,因此连接条件
s1.Rollno=s2.Rollno
无论哪种方式都满足

一行的
id
值小于另一行,因此为了满足连接条件
s1.id>s2.id
,我们知道
s2
是id为1的第一行,
s1
是id为5的第二行

因此,连接条件的两个术语一起保证
s1
s2
将引用具有相同Rollno的两行,并且
s2
将具有较小的
id

+----+--------+----------+-----------+------+
| id | Rollno | LastName | FirstName | Gpa  |
+----+--------+----------+-----------+------+
|  1 |      1 | Aa       | A         |  8.5 | <-- s2
|  5 |      1 | Aa       | A         |  8.5 | <-- s1
+----+--------+----------+-----------+------+
|id |罗尔诺|姓|名| Gpa|
+----+--------+----------+-----------+------+

|1 | 1 | Aa | A | 8.5 |使用delete语句的限制。请参见回答:删除并重新创建表,并将rollno指定为主键。然后重新进行插入,我可以更准确地了解
s1.id>s2.id
的工作原理。