在SQL Server中获取两个日期时间之间的记录

时间:2015-10-05 07:42:54

标签: sql sql-server tsql

我在我们现有的一个存储过程中找到了以下查询。此查询用于记录两个日期时间值。

SELECT office
FROM   officebudget
WHERE  officeid = @officeid
       AND (
               (CONVERT(DATE, DateFrom) BETWEEN @wkstdate AND @wkenddate)
               OR (CONVERT(DATE, DateTo) BETWEEN @wkstdate AND @wkenddate));

我重写了如下,

SELECT office
FROM   officebudget
WHERE  officeid = @officeid
       AND (
               (
                   bkto.DateFrom >= @wkstdate
                   AND bkto.DateFrom <= @wkenddate
               )
               OR (bkto.DateTo >= @wkstdate
               AND bkto.DateTo <= @wkenddate)
           );

两种情况都得到了相同的结果。但我需要知道上述两个查询都会产生的任何场景 不同的结果?

(P.S:DateFrom,DateTo,@ Wkstdate,@ Wkenddate是datetime个字段)

3 个答案:

答案 0 :(得分:1)

我怀疑您正在重构您的查询以使其成为可搜索的,并在列DateFromDateTo上使用可能的索引。

这些不会产生相同的结果,因为您的查询将省略wkenddate的日期部分等于DateFromDateTo列值的日期部分的行。例如,我们说wkenddate = '20151005'和您的专栏DateFrom = '20151005 15:30'。第一个查询将包含此行,因为两个dateparts相等。并且您的第二个查询将省略此行'20151005 15:30' > '20151005'

考虑这些例子:

DECLARE @t TABLE(d DATETIME)

INSERT INTO @t VALUES
('20151001 10:30'),
('20151004 10:30'),
('20151005 10:30')

DECLARE @wkstdate DATE = '20151001', @wkenddate DATE = '20151005'

SELECT * FROM @t WHERE CAST(d AS DATE) BETWEEN @wkstdate AND @wkenddate
SELECT * FROM @t WHERE d >= @wkstdate AND d <= @wkenddate
SELECT * FROM @t WHERE d >= @wkstdate AND d < DATEADD(dd, 1, @wkenddate)

输出:

2015-10-01 10:30:00.000
2015-10-04 10:30:00.000
2015-10-05 10:30:00.000

2015-10-01 10:30:00.000
2015-10-04 10:30:00.000

2015-10-01 10:30:00.000
2015-10-04 10:30:00.000
2015-10-05 10:30:00.000

你应该重写为:

SELECT office
FROM   officebudget
WHERE  officeid = @officeid
       AND (
               (
                   bkto.DateFrom >= @wkstdate
                   AND bkto.DateFrom < dateadd(dd, 1 , @wkenddate)
               )
               OR (bkto.DateTo >= @wkstdate
               AND bkto.DateTo < dateadd(dd, 1, @wkenddate))
           );

答案 1 :(得分:0)

不同之处在于,在第一个查询中,您对已过滤的列(FateFrom和DateTo)使用了一个函数(CONVERT),如果它存在,则引擎无法使用该索引,因此第一个查询将倾向于慢一点

在第二个查询中,您手动输入了这样的日期:2015-09-30。 最好像这样输入:20150930,因为最后一种形式不依赖于服务器的区域,而第一种形式是。

答案 2 :(得分:0)

在某些情况下,它会给你不同的结果,或者最差的结果。

旧代码具有CONVERT的原因是,开发人员希望确保他正在比较相同的确切数据类型,以避免错误或意外结果。请参阅下面的示例以进一步了解。

这个会返回FALSE:就像给你不同的结果一样。

    DECLARE @date1 DATETIME = GETDATE() --2015-10-05 16:15:54.780 , i used date today
    DECLARE @date2 DATETIME = '20151005'

    IF @date1 = @date2
    BEGIN
        SELECT 'TRUE'
    END
    ELSE
        SELECT 'FALSE'

这个将返回TRUE:类似于给你相同的结果

    DECLARE @date1 DATETIME = CONVERT(DATE,GETDATE())
    DECLARE @date2 DATETIME = CONVERT(DATE,'20151005')

    IF @date1 = @date2
            BEGIN
                SELECT 'TRUE'
            END
            ELSE
                SELECT 'FALSE'

希望我的示例可以帮助您分析您的代码,我的建议是先CONVERT,然后再比较两个日期,以获得准确的结果。