从MySQL表中按日期删除重复数据

问题描述 投票:0回答:3

如何从 MySQL 表中删除昨天的重复数据并保留最新记录?

例如,使用以下数据:

SELECT * FROM data;

| pid | serviceid | id             | created
| ----| ----------|----------------|---------
| 10  | ABNCKN    | Q0CHZ2GI1VKOPL | 2022-06-14 10:49:34
| 11  | ABNCKN    | Q0CHZ2GI1VKOPL | 2022-06-14 10:49:34
| 12  | KSPSLS    | QLSPDF0S0SDFKK | 2022-06-15 11:44:21
| 13  | AKNKSL    | QLSPDF0S0SDFKK | 2022-06-15 12:51:42
| 14  | AKNKSL    | QLSPDF0S0SDFKK | 2022-06-15 12:51:42

我用过

DELETE n1 FROM data n1, data n2 WHERE n1.pid < n2.pid AND n1.id = n2.id

如何删除以仅删除重复项并保留昨天数据的最新 pid?

预期输出为

SELECT * FROM data;

| pid | serviceid | id             | created
| ----| ----------|----------------|---------
| 10  | ABNCKN    | Q0CHZ2GI1VKOPL | 2022-06-14 10:49:34
| 11  | ABNCKN    | Q0CHZ2GI1VKOPL | 2022-06-14 10:49:34
| 12  | KSPSLS    | QLSPDF0S0SDFKK | 2022-06-15 11:44:21
| 14  | AKNKSL    | QLSPDF0S0SDFKK | 2022-06-15 12:51:42

删除

| 13  | AKNKSL    | QLSPDF0S0SDFKK | 2022-06-15 12:51:42

mysql sql duplicates sql-delete
3个回答
1
投票
DELETE * FROM data WHERE id IN (SELECT id FROM data WHERE name="ABNCKN" LIMIT((SELECT COUNT(name) FROM data WHERE name="ABNCKN") - 1)));

SELECT id FROM data WHERE name="ABNCKN"
>> 该查询将获取所有具有特定名称的 id,并且 limit 将限制返回的行数。行数将根据除一行之外的重复行而动态变化。您可以在查询中添加 ORDER BY 来排列它们。

最后删除除一行之外的所有重复行。


0
投票

不太明白为什么在预期输出中保留一些重复的数据,但你可以尝试使用 JOIN 获取最后一个 Id 并从 WHERE 中过滤它,这样就不会被删除:

DELETE d1 FROM data d1, data d2
JOIN (SELECT MAX(pid) pid FROM data) d3
WHERE d1.pid != d3.pid AND d1.pid < d2.pid AND d1.id = d2.id;

0
投票

您可以使用自连接来实现此目的并添加条件以仅删除昨天的数据:

DELETE t1 FROM data t1 
  INNER JOIN data t2 
  ON t1.pid < t2.pid 
    AND t1.serviceid = t2.serviceid 
    AND t1.id = t2.id
    AND t1.created = t2.created
  WHERE CAST(t1.created AS DATE) = DATE_ADD(CURRENT_DATE(), INTERVAL -1 DAY);
    
SELECT * FROM data;

看到这个db<>小提琴

对于 MySQL 8+,您还可以使用

ROW_NUMBER()
来实现此目的:

WITH CTE AS
(
  SELECT *, ROW_NUMBER() OVER(PARTITION BY serviceid,id,created ORDER BY pid DESC) AS RN
  FROM data
  WHERE CAST(created AS DATE) = DATE_ADD(CURRENT_DATE(), INTERVAL -1 DAY)
)
DELETE data
FROM data
JOIN CTE ON data.pid=CTE.pid
WHERE CTE.RN>1;

SELECT * FROM data;

检查这个db<>小提琴

删除后输出:

pid 服务ID id 已创建
10 ABNCKN Q0CHZ2GI1VKOPL 2022-06-18 07:27:35
11 ABNCKN Q0CHZ2GI1VKOPL 2022-06-18 07:27:35
12 KSPSLS QLSPDF0S0SDFKK 2022-06-19 07:27:35
14 AKNKSL QLSPDF0S0SDFKK 2022-06-19 07:27:35
© www.soinside.com 2019 - 2024. All rights reserved.