如何将列值与声明的变量进行比较

How to compare column values to declared variable

有人问我这个面试问题。

--Without modifying the following code:

DECLARE @StartDateInput SMALLDATETIME = '1/1/2018',
            @EndDateInput SMALLDATETIME = '1/1/2018'

--Modify the following query so that it will return contacts modified at any time on January 1st, 2018
SELECT *
FROM   dbo.Contacts

我尝试了以下查询,但这不正确。我确定我也应该使用 @EndDateInput 变量,但我不确定如何使用它。我也不认为这通常是处理此问题的正确方法。

SELECT *
FROM dbo.Contacts
WHERE  ModifiedDate = SMALLDATETIME

看来问题是在试探你对日期和日期时间类型的理解,即有时间的日期在没有时间的日期之后(如果有的话;大多数无时间日期被认为是相关日期的午夜,这也是一个时间.. 1.0 与 1 相同,1.1 在 1.0 之后)

我会使用一个范围:

SELECT *
FROM   dbo.Contacts
WHERE ModifiedDate >= @StartDateInput AND ModifiedDate < DATEADD(DAY, 1, @EndDateInput)

为什么?

  • 这适用于具有时间分量的日期时间。
  • 它不会修改行数据(这总是一个坏主意,例如,将一百万个日期时间转换为一个日期只是为了去掉时间,每次查询 - 排除在列上使用索引并且是大量资源浪费)只是为了执行查询。
  • 它将两个@variables 相同所隐含的明显的“结束日期包含在内”转换为允许 < 的独占行为包含在内地工作的形式(增加一天然后减少行数比第二天,从而包括 23:59:59.999999 ...)

我唯一要说的是,严格来说,规范只要求一天的记录,这意味着根本不强制使用@EndDateInput。使用它似乎是合乎逻辑的,但可以争论的是,如果规范是此查询只会 return 一天,则可以丢弃 @End 变量并在 @Start 上执行 DATEADD 而不是

它说的是“任何时间”,意思是考虑时间因素。使用 T-SQL 唯一可靠的方法是使用 >= 和 < 范围查询(不包括上限):

SELECT *
FROM dbo.Contacts
WHERE  ModifiedDate >= @StartDateInput and 
       ModifiedDate < dateadd(d, 1, @EndDateInput);

PS:@StartDateInput 和@ENDDateInput 的初始声明不稳健,可能是偶然指向 2018 年 1 月 1 日。如果它是“1/2/2018”,那么它在 1 月之间会不明确2 日和 2 月 1 日。最好使用 ODBC 规范 and\or ISO 8601 字符串,例如“20180101”。