使用 SMALLDATETIME 变量选择在特定日期修改的记录

问题描述 投票:0回答:2

在面试中遇到 SQL 挑战,需要一些帮助。任务是使用两个 SMALLDATETIME 变量 @StartDateInput 和 @EndDateInput 修改给定查询,以返回 2018 年 1 月 1 日任意时间修改的所有联系人。

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


Query to modify

SELECT *
FROM   dbo.Contacts;

我尝试修改查询,但无法弄清楚如何正确合并@EndDateInput。我的尝试是:

SELECT *
FROM dbo.Contacts
WHERE ModifiedDate = SMALLDATETIME;

但是,这种做法似乎不正确。我认为解决方案应该同时涉及@StartDateInput和@EndDateInput,以准确捕获2018年1月1日任何时间修改的联系人,但我不确定如何实现这一点。

有人可以建议修改此查询以满足指定条件的正确方法吗?

sql-server t-sql declare
2个回答
2
投票

看起来问题是在探讨您对日期和日期时间类型的理解,即带时间的日期在不带时间的日期之后(如果有这样的事情的话;大多数永恒的日期被认为是相关日期的午夜)日期,它也是一个时间..就像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。使用它似乎是合乎逻辑的,但有人可能会说,如果规范规定此查询只会返回一天,则可以丢弃 @End 变量,并在 @Start 上执行 DATEADD


2
投票

它说“任何时间”,意思是考虑时间部分。对于 T-SQL,唯一可靠的方法是使用 >= 和 < range query (exclusive upper range):

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 规范和/或 ISO 8601 字符串,例如“20180101”。

© www.soinside.com 2019 - 2024. All rights reserved.