查找最接近指定日期时间的记录

时间:2019-04-04 14:58:06

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

我正在尝试从最接近指定日期和时间的表中检索数据,例如,您会在下面看到一些有关门的数据,以及它们是否在特定时间打开和关闭。我要检索更接近特定时间的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查询来实现此目的以及我的查询是怎么错的。预先感谢。

3 个答案:

答案 0 :(得分:2)

不使用聚合。使用过滤:

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)上使用索引应该是合理的。

答案 1 :(得分: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条件可确保没有最接近目标日期的记录。

答案 2 :(得分:1)

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

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