【问题标题】:Weeding out duplicates based on comparisons of multiple fields基于多个字段的比较剔除重复项
【发布时间】:2012-11-16 21:40:57
【问题描述】:

我正在开发一个系统,该系统接收和解析以结构化方式格式化的电子邮件,并将信息保存到 MySQL 数据库中。每封电子邮件都描述了一个特定的事件。但是,有时单个事件可能会生成多封电子邮件,因为调度员更新事件详细信息时会发送一封新电子邮件。随着新信息的添加,这可能会在几分钟内发生多次。

我正在尝试编写一个查询,该查询将仅选择描述给定事件的最新行。

下面是表格的外观示例。注意EventID34 指的是同一个事件。事件4 只是最近收到的包含更多详细信息的电子邮件。人类可以快速查看地址、事件类型和接收时间,并推断它们指的是同一事件。问题是:我如何才能将其转换为具有合理准确性的查询?

EventID    EventReceived        EventAddress        EventType      EventDetails
4          11-15-2012 22:55     1234 Anywhere Ln    Fall           In backyard. Possible fracture.
3          11-15-2012 22:54     1234 Anywhere Ln    Fall           In backyard.
2          11-15-2012 17:04     4321 Freedom Ct     Heart Attack   Short of breath. Took 2 NTG.
1          11-15-2012 13:43     9871 Main St        Traffic Crash  2 vehicles in intersection. Fluid leaking from vehicle.

当我查询数据库时,我希望收到的是这样的:

EventID    EventReceived        EventAddress        EventType      EventDetails
4          11-15-2012 22:55     1234 Anywhere Ln    Fall           In backyard. Possible fracture.
2          11-15-2012 17:04     4321 Freedom Ct     Heart Attack   Short of breath. Took 2 NTG.
1          11-15-2012 13:43     9871 Main St        Traffic Crash  2 vehicles in intersection. Fluid leaking from vehicle.

一开始我是这样尝试的:

SELECT * FROM table_name WHERE (EventID) IN (SELECT MAX(EventID) FROM table_name GROUP BY EventAddress) ORDER BY EventReceived DESC;

一般来说,它似乎可以工作,尽管至少有两个问题:

  • 查询速度非常慢,即使有几百条记录(约 15 秒)
  • 我怀疑我错过了EventAddress 相同的事件,但是这些事件相隔几天。这些显然不是同一个事件,但可能会被汇总,因为我只在分组地址中抓取最高的EventID

所以:

  • 如何提高查询效率,以及
  • 如何说明时间因素的重要性? (我可以对应该被视为同一事件的事件施加任意时间限制;例如 15 分钟)。

是否建议将此逻辑放在我的应用程序中而不是依赖 SQL 查询?

感谢所有做到这一点并提出任何可能有用的想法的人!

注意:我查看了this question,认为它可能会有所帮助,但我不确定我是否可以使它工作,因为时间不会完全相同。

【问题讨论】:

    标签: mysql sql optimization duplicates


    【解决方案1】:

    一种可能的优化解决方案是运行频繁的进程来删除重复项。

    例如:每 10 分钟运行一次脚本,以检查过去 10-11 分钟内的所有记录,识别重复项并将其删除。

    脚本执行的频率及其运行的时间段最好由您的系统要求决定。

    【讨论】:

      【解决方案2】:

      你可以试试这样的:

      SELECT t1.* 
      FROM table_name t1
      LEFT JOIN table_name t2 ON t2.EventAddress = t1.EventAddress AND t2.EventReceived > t1.EventReceived 
      WHERE t2.EventID IS NULL
      

      我目前无法测试语法,但想法是针对较新的相同事件自行加入表,并仅保留没有较新条目的事件。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-02-12
        • 1970-01-01
        • 2011-12-18
        • 2022-11-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-03
        相关资源
        最近更新 更多