如何通过DATE或CAST函数在SQL中剔除日期字段的时间信息?

2026-04-27 17:491阅读0评论SEO教程
  • 内容介绍
  • 相关推荐

本文共计877个文字,预计阅读时间需要4分钟。

如何通过DATE或CAST函数在SQL中剔除日期字段的时间信息?

MySQL、PostgreSQL(14+)、SQLite 都支持 `DATE()` 函数,它直接提取时间戳中的日期部分,只保留年、月、日,不包括时间。注意,并非所有数据库都叫这个名字——例如 SQL Server 没有这个 `DATE()` 函数,使用它会导致错误 `Invalid column name 'DATE'`。

常见错误是把 DATE() 当作类型转换函数乱套,比如写成 DATE(CAST(created_at AS DATE)),纯属冗余;只要字段是 DATETIMETIMESTAMP 类型,DATE(created_at) 就够了。

  • MySQL:✅ 支持,WHERE DATE(order_time) = '2024-05-20'
  • PostgreSQL:✅ 14+ 支持,旧版需用 created_at::DATE
  • SQLite:✅ 支持,DATE('now') 也行
  • SQL Server:❌ 不支持,会提示“无法解析的函数名”

SQL Server 必须用CAST(... AS DATE)CONVERT(DATE, ...)

SQL Server 的 DATE 是一种独立数据类型,不能当函数用。想截掉时间,得显式类型转换。用 CAST 更标准,CONVERT 多一个风格参数但没必要。

别写 CAST(created_at AS DATETIME) —— 这没变;也别漏掉括号,CAST created_at AS DATE 语法错误,必须带圆括号。

  • 正确:WHERE CAST(order_date AS DATE) = '2024-05-20'
  • 也行:WHERE CONVERT(DATE, order_date) = '2024-05-20'
  • 错误:CAST order_date AS DATE(缺括号)
  • 错误:CAST(order_date AS DATETIME)(没去掉时间)

WHERE条件里对日期列用函数可能让索引失效

无论用 DATE() 还是 CAST,只要在列上套函数,大多数数据库就无法走 order_date 字段上的 B-tree 索引。查询一慢,容易误判成数据量大,其实是执行计划走了全表扫描。

更高效的做法是改写为范围查询,例如把 DATE(order_time) = '2024-05-20' 换成:

WHERE order_time >= '2024-05-20' AND order_time < '2024-05-21'

这样能命中索引,尤其在千万级订单表里,响应时间可能从秒级降到毫秒级。

  • 适用所有数据库,不依赖函数支持
  • 注意右边界用 < 而非 <=,避免跨天误差
  • 如果字段是 TIMESTAMP WITH TIME ZONE,还得考虑时区归一化

Oracle 和 BigQuery 的写法差异容易踩坑

Oracle 没有 DATE() 函数,也不支持 CAST(... AS DATE) 直接去时间——它的 DATE 类型本身就含时间,得用 TRUNC()。BigQuery 则强制要求用 DATE(),且参数必须是 TIMESTAMP,传 STRING 会报 No matching signature for function DATE

  • Oracle:WHERE TRUNC(order_time) = DATE '2024-05-20'(注意字面量写法)
  • BigQuery:WHERE DATE(order_time) = DATE '2024-05-20',若字段是字符串,先用 PARSE_TIMESTAMP
  • 别在 Oracle 里写 CAST(order_time AS DATE) —— 类型没变,时间还在
  • BigQuery 中 DATE('2024-05-20') 合法,但 DATE('2024/05/20') 会失败
函数名和类型关键字大小写不敏感,但字符串字面量格式、时区隐含行为、索引友好度这些细节,才是线上查不出数据或查得太慢的真正原因。

本文共计877个文字,预计阅读时间需要4分钟。

如何通过DATE或CAST函数在SQL中剔除日期字段的时间信息?

MySQL、PostgreSQL(14+)、SQLite 都支持 `DATE()` 函数,它直接提取时间戳中的日期部分,只保留年、月、日,不包括时间。注意,并非所有数据库都叫这个名字——例如 SQL Server 没有这个 `DATE()` 函数,使用它会导致错误 `Invalid column name 'DATE'`。

常见错误是把 DATE() 当作类型转换函数乱套,比如写成 DATE(CAST(created_at AS DATE)),纯属冗余;只要字段是 DATETIMETIMESTAMP 类型,DATE(created_at) 就够了。

  • MySQL:✅ 支持,WHERE DATE(order_time) = '2024-05-20'
  • PostgreSQL:✅ 14+ 支持,旧版需用 created_at::DATE
  • SQLite:✅ 支持,DATE('now') 也行
  • SQL Server:❌ 不支持,会提示“无法解析的函数名”

SQL Server 必须用CAST(... AS DATE)CONVERT(DATE, ...)

SQL Server 的 DATE 是一种独立数据类型,不能当函数用。想截掉时间,得显式类型转换。用 CAST 更标准,CONVERT 多一个风格参数但没必要。

别写 CAST(created_at AS DATETIME) —— 这没变;也别漏掉括号,CAST created_at AS DATE 语法错误,必须带圆括号。

  • 正确:WHERE CAST(order_date AS DATE) = '2024-05-20'
  • 也行:WHERE CONVERT(DATE, order_date) = '2024-05-20'
  • 错误:CAST order_date AS DATE(缺括号)
  • 错误:CAST(order_date AS DATETIME)(没去掉时间)

WHERE条件里对日期列用函数可能让索引失效

无论用 DATE() 还是 CAST,只要在列上套函数,大多数数据库就无法走 order_date 字段上的 B-tree 索引。查询一慢,容易误判成数据量大,其实是执行计划走了全表扫描。

更高效的做法是改写为范围查询,例如把 DATE(order_time) = '2024-05-20' 换成:

WHERE order_time >= '2024-05-20' AND order_time < '2024-05-21'

这样能命中索引,尤其在千万级订单表里,响应时间可能从秒级降到毫秒级。

  • 适用所有数据库,不依赖函数支持
  • 注意右边界用 < 而非 <=,避免跨天误差
  • 如果字段是 TIMESTAMP WITH TIME ZONE,还得考虑时区归一化

Oracle 和 BigQuery 的写法差异容易踩坑

Oracle 没有 DATE() 函数,也不支持 CAST(... AS DATE) 直接去时间——它的 DATE 类型本身就含时间,得用 TRUNC()。BigQuery 则强制要求用 DATE(),且参数必须是 TIMESTAMP,传 STRING 会报 No matching signature for function DATE

  • Oracle:WHERE TRUNC(order_time) = DATE '2024-05-20'(注意字面量写法)
  • BigQuery:WHERE DATE(order_time) = DATE '2024-05-20',若字段是字符串,先用 PARSE_TIMESTAMP
  • 别在 Oracle 里写 CAST(order_time AS DATE) —— 类型没变,时间还在
  • BigQuery 中 DATE('2024-05-20') 合法,但 DATE('2024/05/20') 会失败
函数名和类型关键字大小写不敏感,但字符串字面量格式、时区隐含行为、索引友好度这些细节,才是线上查不出数据或查得太慢的真正原因。