【问题标题】:Find the record nearest to the datetime specified查找最接近指定日期时间的记录
【发布时间】:2019-08-26 09:32:20
【问题描述】:

我正在尝试从最接近指定日期和时间的表中检索数据,例如,您可以在下面看到一些关于门的数据以及它们是否在特定时间打开和关闭。我要检索按DoorTitle 分组的门列表,使其更接近特定时间。样本数据如下

Id    DoorTitle    Status    DateTime
1     Door_1       OPEN      2019-04-04 9:16:22
2     Door_2       CLOSED    2019-04-01 15:46:54
3     Door_3       CLOSED    2019-04-04 12:23:42
4     Door_2       OPEN      2019-04-02 23:37:02
5     Door_1       CLOSED    2019-04-04 19:56:31

假设我想在2019-04-04 23:54:55 找出门的状态,如果它们是打开或关闭的,则可以向我提供按最接近该时间的门标题分组的记录。我试过这个查询,但它确实给了我最接近这次的记录,它只是通过检查DateTime 是否小于2019-04-04 23:54:55 来随机选择它们。

SELECT DoorTitle,Status,DateTime 
FROM Doors 
WHERE DateTime <= '2019-04-04 23:54:55'  
GROUP BY DoorTitle;

运行查询后我想要的结果是按最接近日期和时间的 DoorTitle 分组的门列表,即如下所示指定的 2019-04-04 23:54:55 它应该返回这些结果,但我正在使用的查询没有返回这个。

DoorTitle    Status    DateTime
Door_3       CLOSED    2019-04-04 12:23:42
Door_2       OPEN      2019-04-02 23:37:02
Door_1       CLOSED    2019-04-04 19:56:31

让我知道我可以使用什么 sql 查询来实现这一点以及我的查询是如何出错的。提前致谢。

【问题讨论】:

    标签: mysql sql date select greatest-n-per-group


    【解决方案1】:

    不要使用聚合。使用过滤:

    SELECT d.*
    FROM Doors d
    WHERE d.DateTime = (SELECT MAX(d2.DateTime)
                        FROM doors d2
                        WHERE d2.DoorTitle = d.DoorTitle AND
                              d2.DateTime <= '2019-04-04 23:54:55'
                       );
    

    使用doors(DoorTitle, DateTime) 上的索引,性能应该是合理的。

    【讨论】:

      【解决方案2】:

      我会使用带有NOT EXISTS 条件的相关子查询:

      SELECT DoorTitle, Status, DateTime
      FROM Doors t
      WHERE 
          DateTime < '2019-04-04 23:54:55'
          AND NOT EXISTS (
              SELECT 1
              FROM Doors t1
              WHERE  t1.DateTime < '2019-04-04 23:54:55' AND t1.DateTime > t.DateTime
          )
      

      NOT EXISTS 条件确保没有最接近目标日期的记录。

      【讨论】:

        【解决方案3】:

        您可以计算每扇门的最新日期时间,然后将结果与原始表格相结合:

        SELECT Doors.*
        FROM (
            SELECT DoorTitle, MAX(DateTime) AS MaxDateTime
            FROM Doors
            WHERE DateTime <= '2019-04-04 23:54:55'
            GROUP BY DoorTitle
        ) AS sq
        JOIN Doors ON sq.DoorTitle = Doors.DoorTitle AND sq.MaxDateTime = Doors.DateTime
        

        【讨论】:

          猜你喜欢
          • 2015-02-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-06-04
          • 2021-07-19
          • 2022-01-21
          • 1970-01-01
          相关资源
          最近更新 更多