好的..所以我已经看了很多关于这个主题的主题,我已经尝试了很多查询来得到我想要的结果,所以你可能已经猜到我仍然没有找到解决方案。
我有一个客户定期将信息上传到与发票有关的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
)
)
如果有人能提供帮助,我们将非常感激!
由于
答案 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}})