【问题标题】:T-SQL - query for records before and after current time in same statementT-SQL - 在同一条语句中查询当前时间之前和之后的记录
【发布时间】:2012-02-01 22:54:02
【问题描述】:

对于您的 T-SQL 专家:

我有下表:

ID              Arrival
1       06:16:00
2       06:17:00
3               07:19:00
4       08:21:00
5       10:22:00
6       13:21:00
7       20:22:00

假设当前时间是 08:00 AM,我想选择 2 条记录前后最接近现在的时间。结果应返回 ID 为 2、3、4、5 和 6 的记录。

在 ID=4 的记录之前和之后获取记录是直截了当的,但到目前为止,我无法弄清楚如何将完整集作为同一查询的一部分返回。我有这两个选择语句:

SELECT TOP(2) * FROM Schedules 
where (datepart(hour, Arrival) - datepart(hour, getdate()))*60 + datepart(minute, Arrival) - datepart(minute, getdate())  < 0
order by (datepart(hour, Arrival) - datepart(hour, getdate()))*60 + datepart(minute, Arrival) - datepart(minute, getdate())

SELECT TOP(2) * FROM Schedules 
where (datepart(hour, Arrival) - datepart(hour, getdate()))*60 + datepart(minute, Arrival) - datepart(minute, getdate())  >= 0
order by (datepart(hour, Arrival) - datepart(hour, getdate()))*60 + datepart(minute, Arrival) - datepart(minute, getdate()) asc

返回之前和之后的记录。我尝试在两个语句上使用联合,但这需要删除第一个 order by 子句,这会使我的查询条件无效。

任何想法都会有所帮助,谢谢。

【问题讨论】:

    标签: sql tsql datetime


    【解决方案1】:

    我们可以使用ROW_NUMBER来划分是否到达之前或之后,并按到达时间与输入时间之间的差的绝对值排序。

    DECLARE @CurrentTime as  time 
    SET @CurrentTime = '08:00 AM'
    
    DECLARE @Schedules  table  (id int, arrival time)
    INSERT INTO @Schedules
    VALUES (1 , '06:16:00' ),
    (2, '06:17:00' ),
    (3, '07:19:00'),
    (4, '08:21:00'),
    (5, '10:22:00'),
    (6, '13:21:00'),
    (7, '20:22:00')
    
    DECLARE @closestTime as time
    SELECT TOP 1 @closestTime = arrival  FROM @Schedules ORDER BY ABS(DATEDIFF(mi, @CurrentTime ,arrival))
    
    ;WITH cte 
         AS (SELECT id, 
                    arrival, 
                    Row_number() OVER (PARTITION BY (CASE WHEN @closestTime > arrival THEN 1 
                                                          WHEN @closestTime < arrival THEN 2 END) 
                                       ORDER BY Abs(Datediff(mi, @closestTime, arrival))) rn 
             FROM   @Schedules) 
    SELECT * 
    FROM   cte 
    WHERE  rn < 3 
            OR arrival = @closestTime 
    ORDER  BY id
    

    结果

    id          arrival          rn
    ----------- ---------------- --------------------
    2           06:17:00.0000000 2
    3           07:19:00.0000000 1
    4           08:21:00.0000000 1
    5           10:22:00.0000000 1
    6           13:21:00.0000000 2
    

    data.se query查看工作示例

    【讨论】:

    • 哇,这个答案。永远不会想到这个给定的时间限制。再次感谢您的链接。
    【解决方案2】:

    您可以尝试以下方法吗?我已经测试了,得到了你想要的结果

    create table Arriavel (ID int, Arr_time time)
    
    insert into Arriavel values (1, '06:16:00')
    insert into Arriavel values (2, '06:17:00')
    insert into Arriavel values (3, '07:19:00')
    insert into Arriavel values (4, '08:21:00')
    insert into Arriavel values (5, '10:22:00')
    insert into Arriavel values (6, '13:21:00')
    insert into Arriavel values (7, '20:22:00')
    
    
    declare @cur_time time
    
    set @cur_time = '08:00:00'
    
    select max(arr_time) arr_time
    from Arriavel
    where arr_time < @cur_time
    
    union all
    
    select min(arr_time) arr_time
    from Arriavel
    where arr_time > @cur_time
    

    【讨论】:

    • "结果应该返回 ID 为 2、3、4、5 和 6 的记录" 你的 SQL 只返回 3 和 4 的时间
    猜你喜欢
    • 1970-01-01
    • 2010-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多