SQL Server解惑——为什么你的查询结果超出了查询时间范围

原文:SQL Server解惑——为什么你的查询结果超出了查询时间范围

废话少说,直接上SQL代码(有兴趣的测试验证一下),下面这个查询语句为什么将2008-11-27的记录查询出来了呢?这个是同事遇到的一个问题,个人设计了一个例子。

USE AdventureWorks2014;
GO

SELECT *  FROM [Person].[Person]

WHERE ModifiedDate >= ‘2008-11-26 00:00:00:000‘

  AND ModifiedDate <= ‘2008-11-26 23:59:59.999‘

其实如果细看过文档的话,应该知道是什么原因,因为数据类型Datetiem的时间范围:00:00:00 到 23:59:59.997 , 最后部分的范围为0 ~997,官方文档提示,datetime的秒的小数部分精度的有舍入,具体请见下面

datetime 秒的小数部分精度的舍入

如下表所示,将 datetime 值舍入到 .000、.003、或 .007 秒的增量 。


用户指定的值


系统存储的值


01/01/98 23:59:59.999


1998-01-02 00:00:00.000


01/01/98 23:59:59.995

01/01/98 23:59:59.996

01/01/98 23:59:59.997

01/01/98 23:59:59.998


1998-01-01 23:59:59.997


01/01/98 23:59:59.992

01/01/98 23:59:59.993

01/01/98 23:59:59.994


1998-01-01 23:59:59.993


01/01/98 23:59:59.990

01/01/98 23:59:59.991


1998-01-01 23:59:59.990

实验测试验证,998会转换为997,而‘2008-11-26 23:59:59.999‘的话,就会转换为‘2008-11-27 00:00:00.000‘,如下截图所示,所以尤其对数据精确性有要求的地方,要注意这些地方,否则SQL语句得出的结果在逻辑上就有误。

官方文档https://docs.microsoft.com/zh-cn/sql/t-sql/data-types/datetime-transact-sql?view=sql-server-ver15 中也有描述不准确的地方,如下截图所示: 

其实这个是精度问题,如果选择datetime2数据类型,它默认的小数精度更高,不会遇到这个问题,更多细节建议参考官方文档(下面参考资料)

参考资料:

https://docs.microsoft.com/zh-cn/sql/t-sql/data-types/datetime2-transact-sql?view=sql-server-ver15

https://docs.microsoft.com/zh-cn/sql/t-sql/data-types/datetime-transact-sql?view=sql-server-ver15

原文地址:https://www.cnblogs.com/lonelyxmas/p/11833851.html

时间: 2024-11-09 00:08:25

SQL Server解惑——为什么你的查询结果超出了查询时间范围的相关文章

在SQL Server中为什么不建议使用Not In子查询

原文:在SQL Server中为什么不建议使用Not In子查询     在SQL Server中,子查询可以分为相关子查询和无关子查询,对于无关子查询来说,Not In子句比较常见,但Not In潜在会带来下面两种问题: 结果不准确 查询性能低下       下面我们来看一下为什么尽量不使用Not In子句.   结果不准确问题     在SQL Server中,Null值并不是一个值,而是表示特定含义,其所表示的含义是"Unknow",可以理解为未定义或者未知,因此任何与Null值

SQL Server 性能调优4 之书写高效的查询

限制查询的行和列来提高性能 这条规则非常简单,这里就不细说了. 使用搜索可参数化判断(sargable conditions)来提高性能 Sargable 由 Search ARGument Able 简写而来,字面意思是搜索可参数化?还是比较晦涩哎... 总之使用Sargable判断可以帮助查询优化器更有效地利用索引,并提高采用 index seek 的可能性,我们先把所有的操作符分一下组. Sargable操作符 = > >= < <= BETWEEN LIKE (通配符必须出

SQL SERVER 月、季、年统计与常用查询语句汇总

一.SQL SERVER 月.季.年统计查询 --本天 SELECT *FROM dbo.TableName WHERE DATEDIFF(DAY,TimeField,getdate())= 0; --本周 SELECT *FROM dbo.TableName WHERE DATEDIFF(WEEK,TimeField,getdate())= 0; --本月 SELECT *FROM dbo.TableName WHERE DATEDIFF(MONTH,TimeField,getdate())=

SQL Server 的表数据简单操作(表数据查询)

--表数据查询----数据的基本查询-- --数据简单的查询--select * | 字段名[,字段名2, ...] from 数据表名 [where 条件表达式] 例:use 商品管理数据库goselect * from 商品信息表select 商品编号,商品名称,产地 from 商品信息表selelct * from 商品信息表 where 产地='辽宁沈阳' --关键字辅助查询----1)distinct关键字 (用来消除查询结果中的重复行,使用时紧跟在select命令后)--select

SQL Server 不同数据间建立链接服务器进行连接查询

    在平时查询以及导数据时,经常会遇到需要使用两个数据库里数据的情况,这时就会用到在两个服务器之间建立一个链接,进行操作,脚本语句如下: 举例:例如你在测试服务器上想要查询业务库里的数据信息,此脚本就需要在测试服务器上执行,输入业务服务器的IP地址.业务服务器的账户.密码,然后执行语句即可:反之,如果你需要将测试数据库的数据导入正式库内,就需要在正式库内建立可以连接到测试库的链接. --创建链接服务器 exec sp_addlinkedserver 'ITSV' , '' , 'SQLOLE

Sql Server 存储过程中查询数据无法使用 Union(All)

原文:Sql Server 存储过程中查询数据无法使用 Union(All) 微软Sql Server数据库中,书写存储过程时,关于查询数据,无法使用Union(All)关联多个查询. 1.先看一段正常的SQL语句,使用了Union(All)查询: SELECT ci.CustId --客户编号 , ci.CustNam --客户名称 , ci.ContactBy --联系人 , ci.Conacts --联系电话 , ci.Addr -- 联系地址 , ci.Notes --备注信息 , ai

理解SQL Server的查询内存授予(译)

此文描述查询内存授予(query memory grant)在SQL Server上是如何工作的,适用于SQL 2005 到2008. 查询内存授予(下文缩写为QMG)是用于存储当数据进行排序和连接时的临时中间数据行.查询在实际执行前需要先请求保留内存,所以会存在一个授予的动作. 这样的好处是提高查询的可靠性和避免单个查询占用所有的内存. SQL Server在收到查询时,会执行3个被定义好的步骤来返回用户所请求的结果集. 1.生成编译计划.它包括各种逻辑指令,如怎么联接数据行. 2.生成执行计

在SQL Server 2016里使用查询存储进行性能调优

作为一个DBA,排除SQL Server问题是我们的职责之一,每个月都有很多人给我们带来各种不能解释却要解决的性能问题. 我就多次听到,以前的SQL Server的性能问题都还好且在正常范围内,但现在一切已经改变,SQL Server开始糟糕, 疯狂的事情不能解释.在这个情况下我介入,分析下整个SQL Server的安装,最后用一些神奇的调查方法找出性能问题的根源. 但很多时候问题的根源是一样的:所谓的计划回归(Plan Regression),即特定查询的执行计划已经改变.昨天SQL Serv

阅读查询计划:楼梯SQL Server索引级别9

通过大卫·杜兰特,2011/10/05 该系列 本文是楼梯系列的一部分:SQL Server的阶梯索引 索引数据库设计的基础,告诉开发人员使用数据库设计者的意图. 不幸的是索引时往往是后加上的性能问题出现. 终于在这里是一个简单的系列文章,应该让任何数据库专业迅速"加速" 在整个楼梯,我们经常说一定执行查询以某种方式; 我们引用生成的查询计划来支持我们的声明. 管理工作室的估计和实际查询计划可以帮助您确定受益,或缺乏,你的索引. 因此,这个级别的目的是给你足够的理解的查询计划,您可以: