SQL Server:如何仅比较datetimeoffset与datetime2字段的日期部分
嘿,我完全懂你的需求啦——你就是想只对比这两个日期列的年月日部分,忽略掉时间、小数秒还有时区偏移,这样那条日期相同的记录就不会被WHERE DateTime1 <> DateTime2查出来对吧?
首先得说为啥LEFT函数没生效:因为datetimeoffset和datetime2是原生日期类型,不是字符串,直接对它们用LEFT会触发数据库的隐式转换,这个转换过程的结果可能不稳定(比如不同的默认格式、时区影响),所以靠它来取日期部分很不靠谱。
靠谱的做法确实是用CAST或者CONVERT,直接把两个列转换成只存年月日的DATE类型,这样对比起来就精准多了,给你两种常用方案:
方案1:直接提取存储的年月日(不考虑时区偏移)
如果你只需要对比两个列字面意义上的年月日(比如你的例子里,DateTime1的+00:00时区不影响日期部分),直接转成DATE类型就行:
SELECT * FROM Table1 WHERE CAST(DateTime1 AS DATE) <> CAST(DateTime2 AS DATE)
DATE类型会自动丢弃时间、小数秒和时区信息,只保留YYYY-MM-DD部分,对比起来完全符合你的需求。
方案2:考虑时区偏移(转换为UTC日期后对比)
如果DateTime1的时区偏移需要被考虑(比如它是其他时区的时间,你要转成UTC后再和DateTime2的日期对比),可以先用SWITCHOFFSET把它转成UTC时区,再转成DATE:
SELECT * FROM Table1 WHERE CAST(SWITCHOFFSET(DateTime1, '+00:00') AS DATE) <> CAST(DateTime2 AS DATE)
你的例子里DateTime1已经是+00:00,所以两种方案结果一样,但如果后续有其他时区的记录,这个方法会更准确。
补充:用字符串转换的替代方案
要是你非要用字符串方式处理,记得显式指定格式,别依赖隐式转换:
SELECT * FROM Table1 WHERE CONVERT(VARCHAR(10), DateTime1, 23) <> CONVERT(VARCHAR(10), DateTime2, 23)
这里的23是SQL Server的格式代码,对应标准的YYYY-MM-DD格式,这样转换出来的字符串前10位就是准确的日期部分。不过还是更推荐用CAST转DATE的方法,性能更好,也更直观不容易出错。
内容的提问来源于stack exchange,提问作者Stpete111

