Sql 在Oracle中对日期使用trunc函数的原因
我目前在Oracle数据库的一个项目中工作。我在应用程序代码中观察到,日期几乎从未直接使用过。相反,它们总是与trunc函数(trunc(SYSDATE)、trunc(event_date)等)一起使用 有人能解释一下使用trunc函数而不是直接使用日期的原因吗?您可以使用Sql 在Oracle中对日期使用trunc函数的原因,sql,oracle,Sql,Oracle,我目前在Oracle数据库的一个项目中工作。我在应用程序代码中观察到,日期几乎从未直接使用过。相反,它们总是与trunc函数(trunc(SYSDATE)、trunc(event_date)等)一起使用 有人能解释一下使用trunc函数而不是直接使用日期的原因吗?您可以使用trunc()函数删除日期的时间成分。默认情况下,Oracle中的date数据类型同时存储日期和时间 trunc()函数还接受一个format参数,因此您可以删除日期的其他组件,而不仅仅是时间。例如,您可以精确到最近的小时。但
trunc()
函数删除日期的时间成分。默认情况下,Oracle中的date
数据类型同时存储日期和时间
trunc()
函数还接受一个format参数,因此您可以删除日期的其他组件,而不仅仅是时间。例如,您可以精确到最近的小时。但是,如果没有格式,目的是删除时间组件。您可以使用trunc()
函数删除日期的时间组件。默认情况下,Oracle中的date
数据类型同时存储日期和时间
trunc()
函数还接受一个format参数,因此您可以删除日期的其他组件,而不仅仅是时间。例如,您可以精确到最近的小时。但是,如果没有格式,则目的是删除时间组件。Oracle中的日期不仅有日期部分,还有时间部分。这可能导致查询数据时出现令人惊讶的结果,例如查询
with v_data(pk, dt) as (
select 1, to_date('2014-06-25 09:00:00', 'YYYY-MM-DD hh24:mi:ss') from dual union all
select 2, to_date('2014-06-26 09:00:00', 'YYYY-MM-DD hh24:mi:ss') from dual union all
select 3, to_date('2014-06-27 09:00:00', 'YYYY-MM-DD hh24:mi:ss') from dual)
select * from v_data where dt = date '2014-06-25'
将不返回任何行,因为您将在午夜与2014-06-25进行比较
通常的解决方法是使用TRUNC()
去除时间部分:
with v_data(pk, dt) as (
select 1, to_date('2014-06-25 09:00:00', 'YYYY-MM-DD hh24:mi:ss') from dual union all
select 2, to_date('2014-06-26 09:00:00', 'YYYY-MM-DD hh24:mi:ss') from dual union all
select 3, to_date('2014-06-27 09:00:00', 'YYYY-MM-DD hh24:mi:ss') from dual)
select * from v_data where trunc(dt) = date '2014-06-25'
其他不太常用的解决此问题的方法包括:
- 将带有
并检查是否相等的两个日期转换为_char('YYYY-MM-DD')
- 使用中间条款:
其中dt介于日期“2014-06-25”和日期“2014-06-26”之间
with v_data(pk, dt) as (
select 1, to_date('2014-06-25 09:00:00', 'YYYY-MM-DD hh24:mi:ss') from dual union all
select 2, to_date('2014-06-26 09:00:00', 'YYYY-MM-DD hh24:mi:ss') from dual union all
select 3, to_date('2014-06-27 09:00:00', 'YYYY-MM-DD hh24:mi:ss') from dual)
select * from v_data where dt = date '2014-06-25'
将不返回任何行,因为您将在午夜与2014-06-25进行比较
通常的解决方法是使用TRUNC()
去除时间部分:
with v_data(pk, dt) as (
select 1, to_date('2014-06-25 09:00:00', 'YYYY-MM-DD hh24:mi:ss') from dual union all
select 2, to_date('2014-06-26 09:00:00', 'YYYY-MM-DD hh24:mi:ss') from dual union all
select 3, to_date('2014-06-27 09:00:00', 'YYYY-MM-DD hh24:mi:ss') from dual)
select * from v_data where trunc(dt) = date '2014-06-25'
其他不太常用的解决此问题的方法包括:
- 将带有
并检查是否相等的两个日期转换为_char('YYYY-MM-DD')
- 使用中间条款:
其中dt介于日期“2014-06-25”和日期“2014-06-26”之间
在第二种情况下,Oracle可以在事件日期对索引执行范围扫描,在第一种情况下,它必须执行完整的表扫描。如果表中的列(例如事件日期)被索引,则避免在列上使用trunc,因为如果这样做,Oracle将无法使用索引(否则,可以创建基于函数的索引) 所以不要这样做: 挑选* 从mytable 其中trunc(事件日期)<日期'2014-01-01' 但是相反,你应该这样做 挑选* 从mytable 其中事件日期<日期'2014-01-02'
在第二种情况下,Oracle可以在事件日期对索引执行范围扫描,在第一种情况下,它必须执行完整的表扫描。因为Oracle中的日期也包含时间部分。我猜开发人员希望确保在与“real”datesTRUNC()进行比较时忽略此时间,并且还接受用于重置其他日期组件的可选参数,因为Oracle中的
date
也包含时间部分。我猜开发人员希望确保在与“real”datesTRUNC()进行比较时忽略此时间,同时也接受用于重置其他日期组件的可选参数