T-SQL日期Between条件查询无返回结果异常问题排查
T-SQL查询无数据的原因及修复方案
问题原因分析
1. 时间范围的边界精度问题
GETDATE()返回包含时分秒的当前时间,假设当前是9月15日10:30:00,那么:
- 原逻辑中
@AsAtDate = DATEADD(DAY, -1, @TodaysDate)得到的是9月14日10:30:00 - 查询条件
stat.activity_created BETWEEN @AsAtDate AND @TodaysDate仅覆盖9月14日10:30:00到9月15日10:30:00之间的数据 - 若
stat.activity_created的14日数据都生成于10:30之前,自然不会被纳入范围,导致无结果 - 改成
DATEADD(DAY, -2, @TodaysDate)后,@AsAtDate为9月13日10:30:00,范围覆盖14日全天数据,因此能返回结果
2. 星期几判断的依赖问题
DATEPART(WEEKDAY, @TodaysDate)的返回值受@@DATEFIRST设置影响:
- 默认
@@DATEFIRST=7(周日为一周第一天),此时周一返回2 - 若数据库
@@DATEFIRST被修改为1(周一为第一天),此时周一返回1,你的判断=2会误识别为周二,导致逻辑错误
修复方案
方案1:修正时间范围为自然日边界
将@TodaysDate和@AsAtDate转换为日期零点,确保覆盖全天数据,同时修正原SQL的语法错误:
DECLARE @TodaysDate DATE -- 改用DATE类型,自动截断时分秒 DECLARE @AsAtDate DATE SET @TodaysDate = CAST(GETDATE() AS DATE) PRINT (DATEPART(WEEKDAY, @TodaysDate)) IF DATEPART(WEEKDAY, @TodaysDate) = 2 -- 今天是否为周一? SET @AsAtDate = DATEADD(DAY, -3, @TodaysDate) -- 报表包含周五、周六和周日数据 ELSE SET @AsAtDate = DATEADD(DAY, -1, @TodaysDate) -- 报表包含上一个工作日数据 SELECT * FROM (SELECT --app.short_id, CONVERT(VARCHAR(11), app.created_at, 105) AS [创建日期], CONVERT(VARCHAR(11), stat.activity_created, 105) AS [更新日期] FROM Table1 app LEFT JOIN Table2 stat ON app.appID = stat.appID WHERE stat.activity_created >= @AsAtDate AND stat.activity_created < DATEADD(DAY, 1, @TodaysDate)) T -- 用<次日零点代替BETWEEN,避免时分秒问题
方案2:确保星期几判断不受DATEFIRST影响
使用DATENAME(WEEKDAY, @TodaysDate)直接判断星期名称,或结合@@DATEFIRST计算,避免依赖环境设置:
-- 方法1:直接判断星期名称(适配中文环境) IF DATENAME(WEEKDAY, @TodaysDate) = '星期一' SET @AsAtDate = DATEADD(DAY, -3, @TodaysDate) ELSE SET @AsAtDate = DATEADD(DAY, -1, @TodaysDate) -- 方法2:计算相对周一的偏移,不受DATEFIRST影响 IF ((DATEPART(WEEKDAY, @TodaysDate) + @@DATEFIRST - 2) % 7) = 0 SET @AsAtDate = DATEADD(DAY, -3, @TodaysDate) ELSE SET @AsAtDate = DATEADD(DAY, -1, @TodaysDate)
内容的提问来源于stack exchange,提问作者Prosy A.
相关产品推荐
相关产品推荐

