Oracle转SSMS的T-SQL:NEXT_DAY与TRUNC(SYSDATE)转换求助
Oracle到T-SQL的查询转换方案
首先明确原Oracle语句的逻辑:
筛选
add_dt落在12天前日期之后的第一个周一到6天前日期之后的第一个周一之间的数据,本质上等价于取上周周一到本周周一的区间。
核心函数转换说明
SYSDATE→ T-SQL的GETDATE(),用于获取当前系统时间;TRUNC(SYSDATE)(取日期零点)对应CAST(GETDATE() AS DATE)(转换为DATE类型会自动去除时间部分)。TRUNC(SYSDATE) - N(减N天)→DATEADD(DAY, -N, CAST(GETDATE() AS DATE))。NEXT_DAY(date, 'Monday'):Oracle中返回指定日期之后的第一个周一(若输入日期本身是周一,则返回下一周的周一),T-SQL无直接对应函数,可通过两种方式实现:
方式一:严格对应Oracle逻辑的通用转换
直接模拟NEXT_DAY的行为,不受系统星期起始设置影响:
WHERE -- 保留原有的其他查询条件 AND add_dt BETWEEN -- 对应 Oracle: NEXT_DAY(TRUNC(SYSDATE)-12, 'Monday') DATEADD(DAY, CASE WHEN DATENAME(WEEKDAY, DATEADD(DAY, -12, CAST(GETDATE() AS DATE))) = 'Monday' THEN 7 ELSE (DATEPART(WEEKDAY, '1900-01-01') - DATEPART(WEEKDAY, DATEADD(DAY, -12, CAST(GETDATE() AS DATE))) + 7) % 7 END, DATEADD(DAY, -12, CAST(GETDATE() AS DATE)) ) AND -- 对应 Oracle: NEXT_DAY(TRUNC(SYSDATE)-6, 'Monday') DATEADD(DAY, CASE WHEN DATENAME(WEEKDAY, DATEADD(DAY, -6, CAST(GETDATE() AS DATE))) = 'Monday' THEN 7 ELSE (DATEPART(WEEKDAY, '1900-01-01') - DATEPART(WEEKDAY, DATEADD(DAY, -6, CAST(GETDATE() AS DATE))) + 7) % 7 END, DATEADD(DAY, -6, CAST(GETDATE() AS DATE)) )
方式二:针对原场景的简化版本
原Oracle语句的逻辑等价于筛选add_dt在上周周一到本周周一之间,用更简洁的写法实现:
WHERE -- 保留原有的其他查询条件 AND add_dt BETWEEN -- 上周周一 DATEADD(DAY, DATEDIFF(DAY, '1900-01-01', CAST(GETDATE() AS DATE)) / 7 * 7 - 7, '1900-01-01') AND -- 本周周一 DATEADD(DAY, DATEDIFF(DAY, '1900-01-01', CAST(GETDATE() AS DATE)) / 7 * 7, '1900-01-01')
注:1900-01-01是固定的周一,此写法不受SET DATEFIRST设置的影响,兼容性更强。
内容的提问来源于stack exchange,提问作者LoMills
相关产品推荐
相关产品推荐

