[英]How do I delete rows in mysql where a specific field is duplicated chronologically next to the other duplication
前言
我知道這里已經有許多“刪除重復行”解決方案,但是我覺得我的查詢有很大不同,足以提出一個新問題。
背景
我的表格是按國家/地區列出的所有產品加班價格歷史記錄。 它將無限期保留歷史數據。
我每天都有一個“價格”供稿,其中包含價值7天的產品價格歷史記錄和價值7天的未來產品價格。 數據包含按“國家/地區”,“產品代碼”(sku),“價格”和“起始日期”日期的價格。 沒有“約會日期”; 相關價格(在給定日期)是從“起始日期”字段得出的。
每天都有許多重復項,通常會存在; 因為大部分相同的數據都是日復一日地發送的,所以給定的產品價格最多可能會出現14次; 因為它每天發送超過14天。 我使用“ sku_country_date_index”(“ sku”,“ country”,“ date_from”)的唯一鍵克服了這一點-在這種情況下,可以防止這些類型的重復項。
但是,發送系統不是很聰明,即使價格在上次記錄的上一個日期已經達到該價格,它也會經常發送價格更改數據,例如“ 2015-01-01 @£10”,“ 2015-01-03” @ 10英鎊”。 我想刪除這些不必要的價格行。
此處發布的其他解決方案提供了有關刪除精確重復行的信息; 例如,刪除所有重復行X的產品X的價格的第一行-這是不合適的,因為價格會隨着時間的推移而上升和下降,並且在以后的某個日期可能具有相同的價格(中間價格會發生變化) 。
題
我如何刪除mysql中的行,在該行中,特定字段在時間上按順序重復於其他重復項。
設定
表:
CREATE TABLE IF NOT EXISTS `price` (
`import_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`country` varchar(2) COLLATE utf8_bin DEFAULT NULL,
`sku` varchar(7) COLLATE utf8_bin DEFAULT NULL,
`date_from` date DEFAULT NULL,
`price` decimal(10,2) DEFAULT NULL,
PRIMARY KEY (`import_id`),
UNIQUE KEY `sku_country_date_index` (`sku`,`country`,`date_from`),
KEY `sku_index` (`sku`),
KEY `country_index` (`country`),
KEY `date_from_index` (`date_from`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1;
示例數據:
REPLACE INTO `price`
(`country`, `sku`, `price`, `date_from`)
VALUES
('uk', '123', '10.00', '2015-01-01'),
('uk', '123', '11.00', '2015-01-04'),
('uk', '123', '9.00', '2015-01-06'),
('uk', '123', '9.00', '2015-01-09'),
('uk', '123', '9.00', '2015-01-13'),
('uk', '123', '10.00', '2015-01-16'),
('uk', '123', '9.00', '2015-01-20'),
('uk', '123', '10.00', '2015-01-25'),
('uk', '124', '10.00', '2015-01-06'),
('uk', '125', '10.00', '2015-01-06'),
('ie', '123', '10.00', '2015-01-06'),
('ie', '123', '14.00', '2015-01-07'),
('ie', '125', '10.00', '2015-01-06')
要求:
刪除以下兩行,因為不需要這兩行來確定給定日期的產品價格-
('uk', '123', '9.00', '2015-01-09'),
('uk', '123', '9.00', '2015-01-13'),
該解決方案可以是CREATE或REPLACE語句的一部分-甚至可以是后續的DELETE。
我的方法
以供參考; 以下是我采取的方法; 不幸的是,它刪除了太多的行。 如果價格之間存在其他價格,則不會考慮可以重復的價格。
DELETE FROM `price` WHERE `import_id` IN (
SELECT t1.import_id
FROM `price` t1, `price` t2
WHERE 1
AND t1.date_from > t2.date_from
AND t1.sku = t2.sku
AND t1.price = t2.price
AND t1.country = t2.country
)
因此,如果我對您的理解正確,那么您希望在給定一組記錄(國家/地區,sku和價格相同)的情況下,保留具有最低import_id的一行。
我認為這可以解決問題(警告,未經測試):
DELETE p2.*
FROM price p1
INNER JOIN price p2
ON p2.country = p1.country
AND p2.sku = p1.sku
AND p2.price = p1.price
AND p2.import_id > p1.import_id;
delete d
from t1 d
join t1 dd
on d.import_id = dd.import_id + 1
and d.sku = dd.sku
and d.price = dd.price
and d.country = dd.country
如果表未排序,我們可以使用上述解決方案中的想法來接收不必要的import_id集
set @n:=0;
set @m:=0;
delete
from t1
where t1.import_id in (
select d.import_id
from
(select @n:=@n+1 AS row_number, import_id, country, sku, price, date_from
from t1 order by country, date_from) as d
join
(select @m:=@m+1 AS row_number, import_id,country, sku, price, date_from
from t1 order by country, date_from) as dd
on d.row_number = dd.row_number + 1
and d.sku = dd.sku
and d.price = dd.price
and d.country = dd.country)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.