SQL Server 2012 : finding the closest date, of muliple columns & rows

时间:2021-07-08 01:25:36

I'm struggling with finding the best way to ge the closest value from multiple columns and rows. In the code below I only get the SEQ number from the StartDate, but I also need to know if the EndDate of row 1 is closer than start date compared to @ValidationTime.

我正在努力寻找从多个列和行中获取最接近值的最佳方法。在下面的代码中,我只从StartDate中获取SEQ号,但我还需要知道第1行的EndDate是否比@ValidationTime更接近开始日期。

For example, if @Validationtime is 10:10, row 1 is the closest value, but 10:20 is closer to row 2.

例如,如果@Validationtime是10:10,则第1行是最接近的值,但是10:20更靠近第2行。

In the end, I will only handle the "closest slot" (1 row).

最后,我只会处理“最近的插槽”(1行)。

I hope I explained it in a not too messy way. :)

我希望我以一种不太乱的方式解释它。 :)

DECLARE @ValidationTime as datetime

SET @ValidationTime = '2017-08-29 10:10:00.000'
--SET @ValidationTime = '2017-08-29 10:20:00.000'

DECLARE @table TABLE (ID INT, StartDate datetime, EndDate datetime);

INSERT INTO @table 
VALUES (1, '2017-08-29 08:00:00.000', '2017-08-29 10:00:00.000'),    
       (1, '2017-08-29 10:30:00.000', '2017-08-29 21:00:00.000'),    
       (1, '2017-08-30 08:00:00.000', '2017-08-30 10:00:00.000'),
       (1, '2017-08-30 19:00:00.000', '2017-08-30 21:00:00.000');

SELECT 
    ID, StartDate, EndDate, 
    ROW_NUMBER() OVER (PARTITION BY ID ORDER BY ABS(DATEDIFF(MINUTE, StartDate, @ValidationTime))) AS SEQ
FROM 
    @table

1 个解决方案

#1


0  

Use CASE . . WHEN to check which is nearer

使用CASE。 。何时检查哪个更近

SELECT  ID, 
    StartDate, 
    EndDate, 
    ROW_NUMBER() OVER ( Partition by  ID
                Order by CASE   WHEN ABS(DateDiff(MINUTE,StartDate,@ValidationTime)) < ABS(DateDiff(MINUTE,EndDate,@ValidationTime))
                        THEN ABS(DateDiff(MINUTE,StartDate,@ValidationTime))
                        ELSE ABS(DateDiff(MINUTE,EndDate,@ValidationTime))
                        END
              ) AS SEQ
FROM    @table

#1


0  

Use CASE . . WHEN to check which is nearer

使用CASE。 。何时检查哪个更近

SELECT  ID, 
    StartDate, 
    EndDate, 
    ROW_NUMBER() OVER ( Partition by  ID
                Order by CASE   WHEN ABS(DateDiff(MINUTE,StartDate,@ValidationTime)) < ABS(DateDiff(MINUTE,EndDate,@ValidationTime))
                        THEN ABS(DateDiff(MINUTE,StartDate,@ValidationTime))
                        ELSE ABS(DateDiff(MINUTE,EndDate,@ValidationTime))
                        END
              ) AS SEQ
FROM    @table