【问题标题】:Delete duplicate order ids by keeping the tracking status - mysql通过保持跟踪状态删除重复的订单ID - mysql
【发布时间】:2020-12-12 09:35:23
【问题描述】:

我有一个名为 tracking_history 的表。在此表中将存储包裹跟踪历史记录。由于某些原因,当 checkTrackStatus 函数执行时,所有现有的跟踪状态都在表中重复插入。这是跟踪状态序列。 'ACCEPTED','AT_SENDING_DEPOT','ON_THE_ROAD','AT_DELIVERY_DEPOT','DELIVERED' 我也在该表中保存了跟踪 ID 和订单 ID。因此,我需要为每个订单 ID 提供最新的跟踪状态 ('ACCEPTED','AT_SENDING_DEPOT','ON_THE_ROAD','AT_DELIVERY_DEPOT','DELIVERED'),并且应该删除剩余的重复值。我尝试了以下查询。

`DELETE t1 FROM tracking_history t1, tracking_history t2 
WHERE t1.id < t2.id AND t1.order_id = t2.order_id` 

但此查询仅保留最新记录并删除其余所有记录。 Means I am having all orders ids with DELIVERED Status only. 如何通过保持最新状态来删除重复状态?任何帮助将不胜感激。

【问题讨论】:

  • 你可以试试AND t1.status = t2.status吗?您是否确保不再将重复项输入数据库?
  • 你的 MySQL 版本是多少?向我们展示SHOW CREATE TABLE tracking_history\G 的输出。
  • @El_Vanja ,谢谢。它按预期工作。
  • 样本数据和期望的结果会有所帮助。在现实世界中,一个包可能会多次经历相同的状态,因此您需要非常小心这个问题。

标签: php mysql sql inner-join sql-delete


【解决方案1】:

我希望在插入一行时保留 first id 而不是 last id。这是因为其他可能有用的信息——特别是插入时间和插入的人。为此,我会为每个状态保留一行,但将逻辑表述为:

delete th
    from tracking_history th join
         (select order_status, status, min(id) as min_id
          from tracking_history th2
          group by order_status, status
         ) th2
         using (order_status, status)
    where id > min_id;

也就是说,这似乎仍然不对。毕竟,也许状态在多行上是相同的。例如,可能有多次尝试将包裹从仓库移动到地址。您真正想要的是tracking_history每批次 的最新状态。我不知道你是否有某种“批次 id”。但让我假设有什么东西,可能是进入日期,将所有共同价值观联系在一起。

在这种情况下,您需要每个“批次”的最新状态:

delete th
    from tracking_history th join
         (select order_status, entry_date, max(id) as max_id
          from tracking_history th2
          group by order_status, entry_date
         ) th2
         using (order_status, entry_date)
    where id < min_id;

【讨论】:

    【解决方案2】:

    你想要一个关于状态的附加关联子句:

    DELETE t1 
    FROM tracking_history t1
    INNER JOIN tracking_history t2 
        ON  t1.id < t2.id 
        AND t1.order_id = t2.order_id
        AND t1.status = t2.status
    

    我建议进一步更改查询,如下所示:

    DELETE t1 
    FROM tracking_history t1
    INNER JOIN (
        SELECT order_id, status, MAX(id) as id 
        FROM tracking_history 
        GROUP BY order_id, status
    ) t2 
        ON  t1.id < t2.id 
        AND t1.order_id = t2.order_id
        AND t1.status = t2.status
    

    这种方法的好处是每行只匹配一次,与原始查询相反,原始查询可能会多次尝试删除同一行。因此,这更有效 - 并且在某种程度上更安全​​。

    【讨论】:

      猜你喜欢
      • 2013-05-04
      • 2022-11-02
      • 2014-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-21
      相关资源
      最近更新 更多