求助,指定字段相同的数据,删除重复,保留 id 最大值的一条

2019-11-23 00:50:48 +08:00
 uti6770werty

有一张表,表名:machinetbl,字段名用了中文,有如下字段:

id|型号|生产时间|序列号|SPF|重量|大小|InterID|UpdateTime

请问:
(型号,生产时间,InterID,序列号,)这 4 个字段相同的数据,只保留 1 条 id 最大值的记录,重复的数据原表原地删除

这条 MySQL 语句怎么写?

mysql> delete from machinetbl where id in(
select id from machinetbl t where exists(select 1 from machinetbl t2 where t2.型号=t.型号 and t2.生产时间=t.生产时间 and t2.InterID=t.InterID and t2.序列号=t.序列号 and t2.id<t.id))
1093 - You can't specify target table 'machinetbl' for update in FROM clause

折腾了一晚,还是不成,求助

4412 次点击
所在节点    MySQL
8 条回复
k9990009
2019-11-23 01:07:35 +08:00
云一下 not in 分组求最大
uti6770werty
2019-11-23 01:12:28 +08:00
@k9990009 没能明白您意思啊,我今晚看了 N 多例子,其实我也知道网上例子很多的,百度真的很多,但都是根据 1~2 个字段的来判断,像是我这个情况需要 4 个字段做判断的,我也是照葫芦画瓢地改,work 不了,非常头疼,只能现在去睡觉了,明天等直接可用的答案,慢慢的再学习理解。
VEEX6
2019-11-23 02:15:44 +08:00
select max(id) as id from machinetbl group by 型号,生产时间,InterID,序列号 Having Count(*) > 1
取到最大 id 和记录,按条件删除完事
luanjia
2019-11-23 09:20:15 +08:00
1. 根据唯一性确定多列筛选条件,筛选多余数据:

SELECT 型号,生产时间,InterID,序列号
FROM 表
GROUP BY 型号,生产时间,InterID,序列号
HAVING count(1) > 1;


2. 留下 id 最大的数据,选择出重复列待删除数据:
SELECT id as id
FROM 表 a
WHERE (a.型号,a.生产时间,a.InterID,a.序列号)
in
(SELECT 型号,生产时间,InterID,序列号
FROM t_action_applink_lang
GROUP BY 型号,生产时间,InterID,序列号
HAVING count(1) > 1)
and id not in (SELECT max(id)
FROM 表
GROUP BY 型号,生产时间,InterID,序列号
HAVING count(1) > 1)

3. 如果直接从上面选择语句删除重复数据,则会报错.所以给表一个别名
DELETE
FROM t_action_applink_lang
WHERE id in (SELECT id as id
FROM 表 a
WHERE (a.型号,a.生产时间,a.InterID,a.序列号)
in
(SELECT 型号,生产时间,InterID,序列号
FROM t_action_applink_lang
GROUP BY 型号,生产时间,InterID,序列号
HAVING count(1) > 1)
and id not in (SELECT max(id)
FROM 表
GROUP BY 型号,生产时间,InterID,序列号
HAVING count(1) > 1)
)
luanjia
2019-11-23 09:22:21 +08:00
楼中回复好像不能使用 markdown,格式不对的话自己可以复制出去看一下哈:
最终 sql 是:
DELETE
from 表
WHERE id in (SELECT id as id
FROM 表 a
WHERE (a.型号,a.生产时间,a.InterID,a.序列号)
in
(SELECT 型号,生产时间,InterID,序列号
FROM t_action_applink_lang
GROUP BY 型号,生产时间,InterID,序列号
HAVING count(1) > 1)
and id not in (SELECT max(id)
FROM 表
GROUP BY 型号,生产时间,InterID,序列号
HAVING count(1) > 1)) as p);
uti6770werty
2019-11-23 11:11:49 +08:00
@luanjia 感谢感谢,水平有限,一时间理解不了,不过会加紧学习理解。。。

5 楼的答案,似乎是有些格式不对,但琢磨不出 p 附近的括号的问题在哪里。。。。,报错如下:

1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as p)' at line 14
mysql>
wysnylc
2019-11-23 11:36:06 +08:00
java8 stream,一行代码搞定
luanjia
2019-11-23 14:26:59 +08:00
@uti6770werty #6 我之前写过这个 sql,但是表明列名跟你的不一样,所以我在回复中替换你的列名使出现错误;你可以从内层 select 复制出来逐步运行一下。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/622305

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX