【问题标题】:T-SQL Query Returning Items It Shouldn't BeT-SQL 查询返回不应该的项目
【发布时间】:2009-10-01 20:58:33
【问题描述】:

这是场景。有问题的列称为“datein”,它的类型是“datetime”。我有三行,'datein' 的值为'2009-10-01 00:00:00.000'。为什么这个查询会返回上述行?

SELECT  *
FROM    t_call AS tc
WHERE   tc.datein >= '2009-09-30 00:00:00.000'
        AND tc.datein <= '2009-09-30 23:59:59.999'

使用

SELECT  *
FROM    t_call AS tc
WHERE   tc.datein BETWEEN '2009-09-30 00:00:00.000'
        AND '2009-09-30 23:59:59.999'

返回相同的结果

【问题讨论】:

    标签: sql sql-server tsql sql-server-2000


    【解决方案1】:

    这是千分之一秒值缺乏精度。请尝试“.997”。

    MSDN DateTime documentation

    运行这个,你会看到:

    declare @dt datetime
    
    select @dt = '2009-09-30 23:59:59.999'
    select @dt
    

    【讨论】:

    • @GregD:同样缺乏分辨率。 DateTime 时间仅适用于每 3 或 4 毫秒。
    • 太棒了。我已将您的答案标记为正确答案。另外,非常感谢您的链接。 @Joel 感谢您提供更多信息。
    • @Austin 忽略我的评论(我已经删除了)。我将它转换为 smalldatetime 而不是 datetime。
    • SQL Server 2008 的 DATETIME2 日期类型将精确到 100ns 的精度,因此 DATETIME2 不会有这个问题
    【解决方案2】:

    DATETIME accuracy 是 0.00333 秒。所以你需要去 '2009-09-30 23:59:59.998' 所以它不会到 10 月 1 日。

    例如:

    select '2009-09-30 23:59:59.994', 
      cast('2009-09-30 23:59:59.994' as datetime)
    union all select '2009-09-30 23:59:59.995', 
      cast('2009-09-30 23:59:59.995' as datetime)
    union all select '2009-09-30 23:59:59.996', 
      cast('2009-09-30 23:59:59.996' as datetime)
    union all select '2009-09-30 23:59:59.997', 
      cast('2009-09-30 23:59:59.997' as datetime)
    union all select '2009-09-30 23:59:59.998', 
      cast('2009-09-30 23:59:59.998' as datetime)
    union all select '2009-09-30 23:59:59.999', 
      cast('2009-09-30 23:59:59.999' as datetime)
    

    返回:

    2009-09-30 23:59:59.994 2009-09-30 23:59:59.993
    2009-09-30 23:59:59.995 2009-09-30 23:59:59.997
    2009-09-30 23:59:59.996 2009-09-30 23:59:59.997
    2009-09-30 23:59:59.997 2009-09-30 23:59:59.997
    2009-09-30 23:59:59.998 2009-09-30 23:59:59.997
    2009-09-30 23:59:59.999 2009-10-01 00:00:00.000
    

    【讨论】:

      【解决方案3】:

      什么是列类型?如果是日期时间,请尝试将您要比较的值也转换为日期时间;如果它是一个字符串(char、nchar、varchar、nvarchar),你对列使用什么排序规则等?

      【讨论】:

      • 列类型为“日期时间”。我会将它添加到操作中
      【解决方案4】:

      根据MSDN documentation

      1 月 1 日的日期和时间数据, 1753 年至 9999 年 12 月 31 日,至 精确度的百分之一 第二(相当于3.33 毫秒或 0.00333 秒)。 值四舍五入为增量 0.000、0.003 或 0.007 秒,如图所示 在表中。

      从该页面中的给定示例中,您必须以 .997 结束查询才能获得预期的结果。

      【讨论】:

        【解决方案5】:

        编写这些查询的安全方法如下:

        SELECT  *
        FROM    t_call AS tc
        WHERE   tc.datein >= '2009-09-30T00:00:00.000'
                AND tc.datein < '2009-10-01T00:00:00.000''
        

        【讨论】:

          猜你喜欢
          • 2013-06-19
          • 2021-02-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-03-18
          • 2012-05-01
          • 1970-01-01
          相关资源
          最近更新 更多