查询以删除旧记录,但有异常

时间:2013-05-14 15:49:52

标签: mysql

假设我有一张保存价格历史的表格,例如:

 _______________________________________________________
|Make  | Model |  Year  |  price  |    date_of_record   |
|--------------------------------------------------------
|Mazda |   6   |  2008  | 10,000  | 2013-05-13 00:00:00 |
|Mazda |   6   |  2008  | 11,000  | 2012-05-13 00:00:00 |
|Mazda |   6   |  2008  | 12,000  | 2011-05-13 00:00:00 |
|Mazda |   6   |  2008  | 11,750  | 2010-05-13 00:00:00 |
|Honda | Civic |  2000  | 3,000   | 2011-05-13 00:00:00 |
|Honda | Civic |  2000  | 4,000   | 2010-05-13 00:00:00 |
|Honda | Civic |  2000  | 5,000   | 2009-05-13 00:00:00 |
|Honda | Civic |  2000  | 5,050   | 2008-05-13 00:00:00 |
|Acura |   TL  |  2009  | 21,000  | 2010-05-13 00:00:00 |
|--------------------------------------------------------

我想删除超过2年的条目,除非最新条目超过2年。很难说出来,基本上我想最终得到这个:

 _______________________________________________________
|Make  | Model |  Year  |  price  |    date_of_record   |
|--------------------------------------------------------
|Mazda |   6   |  2008  | 10,000  | 2013-05-13 00:00:00 |
|Mazda |   6   |  2008  | 11,000  | 2012-05-13 00:00:00 |
|Honda | Civic |  2000  | 3,000   | 2011-05-13 00:00:00 |
|Acura |   TL  |  2009  | 21,000  | 2010-05-13 00:00:00 |
|--------------------------------------------------------

因此查询将删除马自达超过两年的条目,以及本田和讴歌超过2年的条目,但最新的除外。

只有在价格发生变化时才会将参赛作品插入到表格中,因此如果价格在5年内没有变化,则参赛作品将为5年,但这并不意味着数据不准确。

1 个答案:

答案 0 :(得分:2)

首先,让我们获取所有汽车,品牌,型号,年份和相应的最新“记录日期”的列表。因此,您可以拥有2007年的车辆和2008年的相同品牌/型号,每个车型的最新日期条目为2011-01-01。您可能希望保留2007款和2008款车型的车辆入口,但是,您的示例仅显示旧日期只会分别保留本田Civic和Acural TL的保留数据。

运行此命令,只是为了确认这些结果

SELECT 
      c.`make`,
      c.`model`,
      c.`year`,
      MAX( c.date_of_record ) as LatestRecordDate
   from 
      YourCarPriceTable c
   group by
      c.`make`,
      c.`model`,
      c.`year`
   having
      MAX( c.date_of_record ) < DATE_ADD(CURDATE(),INTERVAL -2 YEAR)

现在,使用此作为基础,通过相同品牌,型号和年份的左连接从当前表中删除。允许删除的两个条件 1)“KeepThese”子查询中找不到匹配项,最新记录日期已超过两年......

2)在“KeepThese”子查询中找到一个匹配项,并且该日期比最近符合KeepThese(太旧)结果集的日期要早。

根据您的数据示例,“KeepThese”结果集应包含

Make   Model   Year   LatestRecordDate
Honda  Civic   2000   2011-05-13 00:00:00
Acura  TL      2009   2010-05-13 00:00:00

因此,您的马自达6将删除2010和2011日期条目的两个条目,因为该条目/型号/年未包含在列表中(通过测试IS NULL)。

您的Honda Civic将删除所有早于2011-05-13最新“KeepThese”值的条目,从而删除2008,2009和2010年的条目。

你的Acura TL没有比单一条目更旧的东西,所以它会被遗弃。

DELETE YPT.* FROM
   YourCarPriceTable YPT
      LEFT JOIN ( SELECT 
                        c.`make`,
                        c.`model`,
                        c.`year`,
                        MAX( c.date_of_record ) as LatestRecordDate
                     from 
                        YourCarPriceTable c
                     group by
                        c.`make`,
                        c.`model`,
                        c.`year`
                     having
                        MAX( c.date_of_record ) < DATE_ADD(CURDATE(),INTERVAL -2 YEAR) ) KeepThese
         ON YPT.`make` = KeepThese.`make`
         AND YPT.`model` = KeepThese.`model`
         AND YPT.`year` = KeepThese.`year`
   where
      (     KeepThese.`make` IS NULL
        AND YPT.date_of_record < DATE_ADD(CURDATE(),INTERVAL -2 YEAR))
      OR
      (      YPT.`make` = KeepThese.`make`
         AND YPT.`model` = KeepThese.`model`
         AND YPT.`year` = KeepThese.`year`
         AND YPT.date_of_record < KeepThese.LatestRecordDate )

子查询在前面处理完毕,然后左键加入到汽车/价格表版本的删除中。