MySQL查询:根据日期删除重复的条目,保留最旧的重复项记录

时间:2014-10-16 11:06:53

标签: mysql

好的..所以我已经看了很多关于这个主题的主题,我已经尝试了很多查询来得到我想要的结果,所以你可能已经猜到我仍然没有找到解决方案。

我有一个客户定期将信息上传到与发票有关的MySQL数据库。表格中有3列:

|------
|Column|Type|Null|Default
|------
|//**invoice**//|int(11)|No|0
|//**barcode**//|int(11)|No|
|//**invoice_date**//|datetime|No|

所以你可以看到有发票,条形码和invoice_date。每个条形码都是独一无二的,但您可以将多个条形码与发票ID相关联。

现在你可能会想:"为什么你不在条形码和invoice_date列上添加一个独特的索引?" - 我确实在这些栏目上有索引。现在你看,这是大规模的球疼痛发挥作用的地方。他们使用扫描仪扫描条形码,然后将其放入CSV。有时这会搞砸,所以会有一个完全相同的记录,但invoice_date引用会有几秒或几分钟不同,所以即使它是相同的,MySQL也不会将其解释为副本。

欺骗记录示例:

|24815|86632|2008-08-21 10:22:50
|24899|86632|2008-09-04 17:12:30
|55555|86632|2008-08-21 10:34:41

所以我需要做的是:

删除所有记录,除了条目代码相同的OLDEST invoice_date记录外。

所以从上面的数据集我需要保留:

|24815|86632|2008-08-21 10:22:50这是最古老的记录。

我尝试过很多疑问。

E.g

DELETE I1 FROM v3_invoices_test I1
LEFT JOIN
(
    SELECT MIN(invoice_date) AS OLDESTRECORD, barcode
    FROM   v3_invoices_test
) I2 
ON I1.barcode = I2.barcode
WHERE OLDESTRECORD > I1.invoice_date

DELETE FROM v3_invoices_test
WHERE (barcode, invoice_date) IN (
    SELECT 
    barcode, 
    invoice_date
    FROM 
        v3_invoices_test I1
    WHERE 
    EXIST (
        SELECT *
        FROM v3_invoices_test I2
        WHERE I1.barcode = I2.barcode
        AND I1.invoice_date < I2.invoice_date
    )
)

如果有人能提供帮助,我们将非常感激!

由于

2 个答案:

答案 0 :(得分:1)

这是你的小提琴: http://sqlfiddle.com/#!2/29375b/1

所以你的查询是:

DELETE FROM v3_invoices_test WHERE invoice NOT IN (
  SELECT invoice FROM (
    SELECT invoice FROM v3_invoices_test JOIN (
      SELECT barcode, MIN(invoice_date) m FROM v3_invoices_test GROUP BY barcode
    ) temp ON t.barcode = temp.barcode AND t.invoice_date = temp.m
  ) a
);

可悲的是,由于#1093(https://stackoverflow.com/a/14302701/1767861),需要第一个子查询。基本上,查询检索按条形码分组的最旧日期,并对所有其他ID应用删除。

答案 1 :(得分:0)

查询:

DELETE t1 
FROM v3_invoices_test AS t1 
JOIN v3_invoices_test as t2 
WHERE t1.id > t2.id 
AND t1.column_name1 = t2.column_name1;

这里您需要id列,就像auto_increment列和 上述查询中的column_name表示删除要提供的数据的基础是哪一列(t1.column_name1 = t2.column_name1),如果删除多于一列的数据,则可以将其添加(和t 1.column_name2 = t2.column_name2)到查询中

最后,您需要根据查询中最旧或最新的数据删除数据,只需更改<或>,就可以为最旧的数据(t1.id > t2.id提供,为最新的({{ 1}})