SQL在两个方向上获取最接近的日期

时间:2018-05-02 09:30:40

标签: sql sql-server

我试图找出一种查询表格的有效方法,我需要在两个方向上输出最接近给定日期的行。

我有一个解决方案,为将来最近的一天

SELECT  top 1 id
   FROM [dbo].[Shipments] 
   WHERE EstimatedArrivalDate < @date
   AND Complete = 0 
   AND (RegNoTrailer = @regNo OR RegNoTruck = @regNo) 
   ORDER BY EstimatedArrivalDate DESC

这是最接近的未来日期,但我也需要检查过去的日期。

5 个答案:

答案 0 :(得分:2)

您可以结合使用DatediffAbs

select abs(DATEDIFF(second,<dateColumn>,<dateParameter>)) result,<otherColumns> 
from <tableName> order by  result

第一张唱片将是最接近的唱片。

答案 1 :(得分:2)

如果您希望此功能高效,则需要正确的索引。如果是这样,我认为可能是一个更复杂的查询:

SELECT TOP 1 id
FROM ((SELECT TOP 1 id, EstimatedArrivalDate
       FROM [dbo].[Shipments] 
       WHERE EstimatedArrivalDate < @date AND
             Complete = 0 
             RegNoTrailer = @regNo
       ORDER BY EstimatedArrivalDate DESC
      ) UNION ALL
      (SELECT TOP 1 id, EstimatedArrivalDate
       FROM [dbo].[Shipments] 
       WHERE EstimatedArrivalDate < @date AND
             Complete = 0 
             RegNoTruck = @regNo 
       ORDER BY EstimatedArrivalDate DESC
      ) UNION ALL
      (SELECT TOP 1 id, EstimatedArrivalDate
       FROM [dbo].[Shipments] 
       WHERE EstimatedArrivalDate > @date AND
             Complete = 0 
             RegNoTrailer = @regNo
       ORDER BY EstimatedArrivalDate ASC
      ) UNION ALL
      (SELECT TOP 1 id, EstimatedArrivalDate
       FROM [dbo].[Shipments] 
       WHERE EstimatedArrivalDate > @date AND
             Complete = 0 
             RegNoTruck = @regNo 
       ORDER BY EstimatedArrivalDate ASC
      )
     )
ORDER BY ABS(DATEDIFF(second, EstimatedArrivalDate, @Date));

对于此查询,您需要两个索引:Shipments(RegNoTruck, Complete, EstimatedArrivalDate)Shipments(RegNoTrailer, Complete, EstimatedArrivalDate)

通过将OR条件拆分为两个单独的子查询,每个子查询可以使用不同的索引。

答案 2 :(得分:1)

尝试使用DATEDIFF函数查找2个日期之间的差异。您还需要添加ABS()函数以满足过去和未来日期

SELECT  top 1 id
   FROM [dbo].[Shipments] 
   WHERE Complete = 0 
   AND (RegNoTrailer = @regNo OR RegNoTruck = @regNo) 
   ORDER BY ABS(DATEDIFF(D,EstimatedArrivalDate,@date)) ASC

答案 3 :(得分:0)

这会有用吗?

   SELECT  top 1 id
   FROM [dbo].[Shipments] 
   WHERE EstimatedArrivalDate > @date --change to >
   AND Complete = 0 
   AND (RegNoTrailer = @regNo OR RegNoTruck = @regNo) 
   ORDER BY EstimatedArrivalDate ASC --change to ASC

或两者一起使用UNION

SELECT  top 1 id
   FROM [dbo].[Shipments] 
   WHERE EstimatedArrivalDate < @date
   AND Complete = 0 
   AND (RegNoTrailer = @regNo OR RegNoTruck = @regNo) 
   ORDER BY EstimatedArrivalDate DESC
UNION
   SELECT  top 1 id
   FROM [dbo].[Shipments] 
   WHERE EstimatedArrivalDate > @date --change to >
   AND Complete = 0 
   AND (RegNoTrailer = @regNo OR RegNoTruck = @regNo) 
   ORDER BY EstimatedArrivalDate ASC --change to ASC

答案 4 :(得分:0)

使用DATEDIFF()和ABS()获取最接近的日期差异

SELECT  top 1 id
   FROM [dbo].[Shipments] 
   WHERE Complete = 0 
   AND (RegNoTrailer = @regNo OR RegNoTruck = @regNo) 
   ORDER BY ABS(DATEDIFF(SECOND, @date, EstimatedArrivalDate))