簡體   English   中英

我如何刪除mysql中的行,其中特定字段在時間上按順序重復於其他重復項

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM