SQL查询SomeDATE列昨日数据失败咨询:函数无结果硬编码可行
嘿,我完全懂你的疑惑——明明逻辑上直接用函数取昨日日期和硬编码应该是一回事,但结果却不一样,肯定是哪里忽略了细节。结合你说的情况(今日2018-02-22),大概率是下面这几个常见的坑:
日期列包含时间部分:
这是最常见的原因!如果你的SomeDATE列是datetime/timestamp类型,里面的记录其实是带时分秒的(比如2018-02-21 10:30:45),而你用函数获取的“昨日日期”可能是不带时间的2018-02-21 00:00:00,直接用=匹配的话,自然找不到那些带时间的记录。
解决办法是把日期列的时间部分截断,只保留日期部分再匹配:
比如SQL Server写法:WHERE CAST(SomeDATE AS DATE) = CAST(DATEADD(day, -1, GETDATE()) AS DATE)MySQL写法:
WHERE DATE(SomeDATE) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)日期函数返回的类型/格式不匹配:
有些数据库函数返回的是字符串类型的日期,而SomeDATE是日期类型,隐式转换时可能因为格式不一致导致匹配失败。比如你用CONVERT(varchar, GETDATE()-1, 120)得到的是字符串,和日期类型的列对比就可能出问题。
解决办法是确保两边都是日期类型的对比,比如用专门的日期函数返回日期类型,而不是字符串。时区差异问题:
如果数据库服务器的时区和你本地时区不一样,函数计算出来的“昨日”可能和你认知的昨日不是同一天。比如你本地是东八区,服务器是UTC时区,那么服务器的“昨日”会比你本地晚8小时,当你在本地2018-02-22上午查询时,服务器的时间可能还是2018-02-21的下午,这时候函数返回的“昨日”其实是2018-02-20,自然查不到记录。
解决办法是调整时区,比如SQL Server用AT TIME ZONE转换,MySQL用CONVERT_TZ函数,确保计算的昨日是你所在时区的日期。
你可以先做个小测试:执行SELECT 你的日期函数看看返回的具体值是什么,再和SomeDATE列里的记录对比,就能很快定位到问题啦!
内容的提问来源于stack exchange,提问作者Talay

