如何通过DATE或CAST函数在SQL中剔除日期字段的时间信息?
- 内容介绍
- 相关推荐
本文共计877个文字,预计阅读时间需要4分钟。
MySQL、PostgreSQL(14+)、SQLite 都支持 `DATE()` 函数,它直接提取时间戳中的日期部分,只保留年、月、日,不包括时间。注意,并非所有数据库都叫这个名字——例如 SQL Server 没有这个 `DATE()` 函数,使用它会导致错误 `Invalid column name 'DATE'`。
常见错误是把 DATE() 当作类型转换函数乱套,比如写成 DATE(CAST(created_at AS DATE)),纯属冗余;只要字段是 DATETIME 或 TIMESTAMP 类型,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分钟。
MySQL、PostgreSQL(14+)、SQLite 都支持 `DATE()` 函数,它直接提取时间戳中的日期部分,只保留年、月、日,不包括时间。注意,并非所有数据库都叫这个名字——例如 SQL Server 没有这个 `DATE()` 函数,使用它会导致错误 `Invalid column name 'DATE'`。
常见错误是把 DATE() 当作类型转换函数乱套,比如写成 DATE(CAST(created_at AS DATE)),纯属冗余;只要字段是 DATETIME 或 TIMESTAMP 类型,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')会失败

