现在用过一张商品表, 现在假设在这张表里,“橘子”这种商品存在重复。可怕的是,这张表 里连主键都没有(其实是根本没法设置主键)。我们现在就需要马上 清理一下,去掉重复行。
以下是 SQL DELETE 语句从 MySQL 数据表中删除数据的通用语法:
DELETE FROM table_name [WHERE Clause]
-- 用于删除重复行的SQL 语句(1) :使用极值函数
DELETE FROM Products P1
WHERE rowid < ( SELECT MAX(P2.rowid)
FROM Products P2
WHERE P1.name = P2. name
AND P1.price = P2.price ) ;
这个关联子查询的处理乍看起来不是很好理解。本来,关联子查询正 如其名,就是用来查找两张表之间的关联性的,而这里只有一张表, 却也跟“关联”扯上了关系,想必大家都心存疑问吧。
之所以大家会有这种疑问,是因为没有从正确的层面来理解这条SQL 语句。请像前面的例题里讲过的一样,将关联子查询理解成对 两个拥有相同数据的集合进行的关联操作。
于是,由于苹果和香蕉没有重复行,所以返回的行是“1:苹果”“5: 香蕉”,而判断条件是不等号,所以该行不会被删除。而对于“橘 子”这个商品,程序返回的行是“4:橘子”,那么 rowid 比 4 小的两行——“2:橘子”和“3:橘子”都会被删除。
“表”“视图”这样的名称只反映了不同的存储方法, 而存储方法并不会影响到 SQL 语句的执行和结果,因此无需有什么 顾虑(在不考虑性能的前提下)
此外,用前面介绍过的非等值连接的方法也可以写出与这里的执行过 程一样的 SQL 语句。请在纸上画一画 P1 和 P2,分析一下它的执行 过程。
-- 用于删除重复行的SQL 语句(2) :使用非等值连接
DELETE FROM Products P1
WHERE EXISTS ( SELECT *
FROM Products P2
WHERE P1.name = P2.name
AND P1.price = P2.price
AND P1.rowid < P2.rowid );