mysql - 删除 MySQL 表中的相同条目
问题描述
我是 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。DELETE的目标表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
ands2
通常称为“表别名”,但您应该将它们视为更像行别名。它们一次引用一行,因此您可以比较各行中的值。
假设有这样的两行:
+----+--------+----------+-----------+------+
| 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
a 值小于另一行,因此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 值较小的“第一”行 ( s2
),并删除另一行 ( s1
)。因此delete s1 from ...
. 在 MySQL 的多表删除语法中,您指定将在from
关键字之前删除哪一行。from
子句 ( )中定义的其他行别名s2
不会被删除。
推荐阅读
- docker - Gitlab中的Nginx日志非常大
- git - Git强制合并
- ms-access - 如何在 Access 中读取超过 255 个字符/行并包含控制字符的 TXT 文件?
- android - Flutter 中 google_sign_in 包的 Google 登录错误
- python - 无法通过 Pycharm 运行部署在远程服务器上的项目
- redirect - dyndns 使用什么样的重定向类型?
- shell - Visual Studio Code 终端外壳与任务外壳缺少 rvm
- java - 比较 HashSet 中的对象
- google-apps-script - Apps 脚本 - 计算可变范围内的行数
- ios - iOS Release Build 无法在 React Native WebView 中加载本地 HTML/JS/CSS 文件