您好!欢迎访问家园网-www.jy.wang!

家园网

讲一下DATEADD(DAY, -1, GETDATE())

网络 作者:本站 点击:


SELECT ISBN,BookName,INTime 数据录入时间 FROM bookinfo_zerobasis WHERE INTime 
BETWEEN
DATEADD(DAY,-1,GETDATE()) 
AND
GETDATE();



这条 SQL 语句的作用是:查询过去 24 小时内(从昨天同一时刻到现在)录入的图书信息

让我逐部分详细解释:


一、整体逻辑

sql

SELECT ISBN, BookName, INTime 数据录入时间 
FROM bookinfo_zerobasis 
WHERE INTime BETWEEN DATEADD(DAY, -1, GETDATE()) AND GETDATE();

  • 查询范围:过去 24 小时内录入的图书

  • 动态日期:使用 GETDATE() 获取当前时间,因此每次查询结果都会不同


二、各部分详解

1. GETDATE()

  • 获取当前系统日期和时间

  • 例如:2026-04-14 15:30:25.123

2. DATEADD(DAY, -1, GETDATE())

  • DATEADD 函数:在日期上增加或减少指定时间间隔

  • DAY, -1:减去 1 天

  • 结果:昨天此时刻

  • 例如:如果现在是 2026-04-14 15:30:25,则结果为 2026-04-13 15:30:25

3. BETWEEN ... AND ...

  • 范围包含两端

  • 查询 INTime 在 昨天此时刻 到 当前时刻 之间的所有记录

4. INTime 数据录入时间

  • 缺少 AS 关键字(但某些数据库允许省略)

  • 标准写法应为:INTime AS 数据录入时间


三、实际示例

假设当前时间是 2026-04-14 15:30:25

sql

WHERE INTime BETWEEN '2026-04-13 15:30:25' AND '2026-04-14 15:30:25'

会查询出:

  • 昨天下午 3:30:25 之后录入的书

  • 到今天下午 3:30:25 之前录入的书

  • 恰好 24 小时的时间窗口


四、⚠️ 潜在问题与改进建议

问题 1:BETWEEN 在精确时间下的行为

  • 如果 INTime 包含毫秒,边界值的毫秒部分可能导致漏数据

  • 更安全的写法(推荐):

sql

SELECT ISBN, BookName, INTime AS 数据录入时间FROM bookinfo_zerobasisWHERE INTime >= DATEADD(DAY, -1, GETDATE())
  AND INTime < GETDATE();

问题 2:缺少 AS 关键字

  • 当前写法 INTime 数据录入时间 在某些数据库(如 Oracle)会报错

  • 标准写法:

sql

SELECT ISBN, BookName, INTime AS 数据录入时间

问题 3:时区问题

  • GETDATE() 返回的是数据库服务器的本地时间

  • 如果用户和服务器在不同时区,查询结果可能不符合预期

  • 解决方案:使用 GETUTCDATE() 统一使用 UTC 时间

sql

WHERE INTime BETWEEN DATEADD(DAY, -1, GETUTCDATE()) AND GETUTCDATE()

问题 4:性能问题

  • 对 INTime 列使用函数或范围查询通常没问题

  • 但确保 INTime 列有索引,否则大表查询会很慢


五、常见变体需求

需求写法
今天录入的数据WHERE INTime >= CAST(GETDATE() AS DATE)
昨天全天数据WHERE INTime >= DATEADD(DAY, -1, CAST(GETDATE() AS DATE)) AND INTime < CAST(GETDATE() AS DATE)
过去 7 天WHERE INTime >= DATEADD(DAY, -7, GETDATE())
本月数据WHERE INTime >= DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1)

六、总结

项目说明
功能查询过去 24 小时录入的图书
优点动态时间,无需手动改日期
缺点边界值可能漏数据;依赖服务器时区
适用场景实时监控、增量同步、今日新增统计
建议改进用 >= 和 < 替代 BETWEEN;明确时区



再讲一下DATEADD(DAY, -1, GETDATE())


DATEADD(DAY, -1, GETDATE()) 详解

这是一个日期计算函数,用于获取昨天此时的准确时间


一、函数拆解

sql

DATEADD(DAY, -1, GETDATE())

组成部分含义示例值
GETDATE()获取当前日期时间2026-04-14 15:30:25.123
DAY指定时间单位是天按天进行计算
-1减少的数量(负数表示往前)减去 1 天
DATEADD在指定日期上增加/减少时间执行计算

结果2026-04-13 15:30:25.123(精确到毫秒)


二、参数详解

1. 第一个参数:时间单位

常用单位有:

单位说明示例
YEAR / YYDATEADD(YEAR, -1, GETDATE()) 去年今日
MONTH / MMDATEADD(MONTH, -3, GETDATE()) 3个月前
DAY / DDDATEADD(DAY, 7, GETDATE()) 7天后
HOUR / HH小时DATEADD(HOUR, 2, GETDATE()) 2小时后
MINUTE / MI分钟DATEADD(MINUTE, -30, GETDATE()) 30分钟前
SECOND / SSDATEADD(SECOND, 10, GETDATE()) 10秒后

2. 第二个参数:增减数量

  • 正数:向未来增加

  • 负数:向过去减少

  • :不变

3. 第三个参数:基准日期

可以是:

  • GETDATE():当前时间

  • '2024-01-01':指定日期

  • 表中的日期列:如 bookinfo_zerobasis.INTime


三、实际计算示例

假设当前时间是 2026-04-14 15:30:25.123

sql

SELECT 
    GETDATE() AS 当前时间,
    DATEADD(DAY, -1, GETDATE()) AS 昨天此时,
    DATEADD(DAY, -2, GETDATE()) AS 前天此时,
    DATEADD(DAY, 1, GETDATE()) AS 明天此时,
    DATEADD(HOUR, -24, GETDATE()) AS 24小时前;  -- 和减1天结果相同

结果

当前时间昨天此时前天此时明天此时24小时前
2026-04-14 15:30:25.1232026-04-13 15:30:25.1232026-04-12 15:30:25.1232026-04-15 15:30:25.1232026-04-13 15:30:25.123

四、在 WHERE 条件中的作用

sql

WHERE INTime BETWEEN DATEADD(DAY, -1, GETDATE()) AND GETDATE()

执行过程

  1. GETDATE() 先执行 → 2026-04-14 15:30:25.123

  2. DATEADD(DAY, -1, ...) 计算 → 2026-04-13 15:30:25.123

  3. BETWEEN 形成范围 → 2026-04-13 15:30:25.123 到 2026-04-14 15:30:25.123

  4. 查询落在该时间段的图书记录

结果:查询出最近24小时内录入的图书(精确到毫秒)


五、常见应用场景

1. 过去 N 天

sql

-- 过去 7 天WHERE INTime >= DATEADD(DAY, -7, GETDATE())-- 过去 30 天WHERE INTime >= DATEADD(DAY, -30, GETDATE())

2. 过去 N 小时

sql

-- 过去 6 小时WHERE INTime >= DATEADD(HOUR, -6, GETDATE())

3. 本月开始至今

sql

WHERE INTime >= DATEADD(DAY, -DAY(GETDATE()) + 1, CAST(GETDATE() AS DATE))

4. 上个月同期

sql

WHERE INTime BETWEEN DATEADD(MONTH, -1, DATEADD(DAY, -1, GETDATE())) 
              AND DATEADD(DAY, -1, GETDATE())


六、与其他数据库的对比

数据库昨天此时的写法
SQL ServerDATEADD(DAY, -1, GETDATE())
MySQLDATE_SUB(NOW(), INTERVAL 1 DAY)
PostgreSQLNOW() - INTERVAL '1 day'
OracleSYSDATE - 1

七、注意事项 ⚠️

1. 保留时间部分

  • DATEADD(DAY, -1, GETDATE()) 保留时分秒毫秒

  • 如果要查昨天全天(00:00:00 到 23:59:59),需用:

sql

-- 昨天开始DATEADD(DAY, -1, CAST(GETDATE() AS DATE))-- 或DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()) - 1, 0)

2. 性能考虑

  • DATEADD 在 WHERE 条件中不影响索引使用(只要列本身没被函数包裹)

  • ✅ 正确:WHERE INTime >= DATEADD(DAY, -1, GETDATE())

  • ❌ 错误:WHERE DATEADD(DAY, 1, INTime) >= GETDATE()(会导致索引失效)

3. 时区问题

  • GETDATE() 返回服务器本地时间

  • 跨时区应用建议用 GETUTCDATE()


八、快速记忆

text

DATEADD(单位, 数量, 基准日期)

         ↓         ↓          ↓
DATEADD(DAY,    -1,    GETDATE())
         ↑         ↑          ↑
       按天     减1天     从当前时间开始

理解为:从当前时间往回数 1 天,得到精确到毫秒的那个时间点


标签: