Oracle关于日期字段的查询

Oracle日期查询:to_char与to_date的陷阱
本文探讨了在Oracle中使用to_char和to_date进行日期字段查询时遇到的问题,包括边界值处理、效率及隐式转换。to_date在between...and中不包含边界值,而to_char可能导致效率下降。同时,介绍了Oracle日期处理的一些细节,如忽略时间部分会取整到日,但忽略月份不会取整到年。
部署运行你感兴趣的模型镜像

最近碰到了这个问题,被啪啪啪的打脸,写下来记录自己的黑历史。流水账,着急的直接穿越到文末看结论。

问题:查询某表在一月份到三月份的数据。

举例:student(id varchar(20),name varchar(20), cretae_time),求1-1到3-31号报道的学生总数。

过程:

自己刚开始写的sql语句如下:select count(*) from student where create_time between to_date('2019/01/01','yyyy/mm/dd') and to_date('2019/03/31','yyyy/mm/dd');

自认为没有什么问题,提交数据,被问到:Oracle比较日期类型直接用between...and不行吗?举个例子:select count(*) from student  s where s.create_time between '2019/01/01' and '2019/03/31';如果修改为:select count(*) from student s where to_char('s.create_time','yyyy/mm/dd') between '2019/01/01' and '2019/03/31';可以吗?

为了XX,自己特意去试了试,还特意测试了一下mysql,回复到:对的,需要使用tochar,或者to_date函数,不然会出现“文字与格式字符不匹配”错误,查不出结果。mysql则可以直接比较,不需要用到函数转换。

接着,莫名其妙的说让我把文件改下,改成用to_char('s.create_time','yyyy/mm/dd')这种形式的。......一堆疑问就出来了,这人有问题?to_char或者to_date效果不一样嘛?人家道:这样日期转字符更紧凑一些,没有能或不能。而且我这样边界值是不对的。

为了反驳,证明真理是掌握在我这里的,又向度娘跟同事询问一波。了解到的有:between ...and是包含边界值的,那岂不是说我的sql没问题???还有就是to_char,to_date都能作日期查询的使用,涉及到了效率问题,又一波oracle sql优化to_date和to_char 的使用的百度 ,接着就想去反驳:我的没问题,between and 是包含边界值的,to_char,to_date都可以用,而且to_date的效率貌似更高!(但有的说要看情况,比如加索引的情况,数据的多少等)。

自己又胆小,建立个数据库测试下,....我和我的小伙伴都惊呆了,竟然,边界值包含不了,没有3月31号的数据,又一波百度。发现了问题,大概就是隐式转换,显示转换什么鬼的,也没看懂。然后又测试了下to_char,和to_date的效率,数据量较少,to_date的效率更点。

那就这样吧,老老实实,周一改sql接着查。参考链接为:https://blog.youkuaiyun.com/weixin_34123613/article/details/89563103

结论:

Oracle关于日期字段的查询,to_char和to_date两个都能用,但是需要注意:to_date会缩小范围,不包括边界值。to_char会降低效率。between ...and虽然包括边界值,但在时间类型上不适用。

另外,

 

to_date(‘2007-06-12 10:00:00’, ‘yyyy-mm-dd hh24:mi:ss’)

当省略HH、MI和SS对应的输入参数时,Oracle使用0作为DEFAULT值。如果输入的日期数据忽略时间部分,Oracle会将时、分、秒部分都置为0,也就是说会取整到日。

同样,忽略了DD参数,Oracle会采用1作为日的默认值,也就是说会取整到月。

但是,不要被这种“惯性”所迷惑,如果忽略MM参数,Oracle并不会取整到年,取整到当前月。

注意:

1.在使用Oracle的to_date函数来做日期转换时,可能会直觉地采用“yyyy-MM-dd HH:mm:ss”的格式作为格式进行转换,但是在Oracle中会引起错误:“ORA 01810 格式代码出现两次”。如:select to_date(‘2005-01-01 13:14:20’,’yyyy-MM-dd HH24:mm:ss’) from dual;

原因是SQL中不区分大小写,MM和mm被认为是相同的格式代码,所以Oracle的SQL采用了mi代替分钟。select to_date(‘2005-01-01 13:14:20’,’yyyy-MM-dd HH24:mi:ss’) from dual;

2.另要以24小时的形式显示出来要用HH24

select to_char(sysdate,’yyyy-MM-dd HH24:mi:ss’) from dual;//mi是分钟

select to_char(sysdate,’yyyy-MM-dd HH24:mm:ss’) from dual;//mm会显示月份

 

 

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

Oracle 数据库中更新日期类型的字段值,可以使用 `UPDATE` 语句来完成。基本语法如下: ```sql UPDATE 表名 SET 日期字段名 = DATE '新日期值' WHERE 条件; ``` 其中: - **表名**:需要更新的表的名称。 - **日期字段名**:需要修改的日期类型字段的名称。 - **新日期值**:要将字段修改为的新日期值,必须确保使用正确的日期格式,例如 `'YYYY-MM-DD'`。 - **条件**:这是一个可选项,用于指定更新记录的条件。如果不提供条件,将会更新表中的所有记录。 以下是一个具体的示例,假设我们有一个名为 `employees` 的表,其中包含一个名为 `hire_date` 的日期类型字段。现在需要将 `hire_date` 修改为新的日期值 `'2023-06-01'`,并且仅针对部门为 `'IT'` 的员工进行更新: ```sql UPDATE employees SET hire_date = DATE '2023-06-01' WHERE department = 'IT'; ``` 此语句会根据 `department` 字段的值是否为 `'IT'` 来决定哪些行需要更新。如果省略 `WHERE` 子句,则表中所有记录的 `hire_date` 字段都会被设置为 `'2023-06-01'` [^1]。 ### 注意事项 1. **日期格式**:在 Oracle 中,日期值通常以 `DATE 'YYYY-MM-DD'` 的形式表示,也可以使用 `TO_DATE()` 函数来处理更复杂的日期格式。 示例: ```sql UPDATE employees SET hire_date = TO_DATE('2023-06-01', 'YYYY-MM-DD') WHERE department = 'HR'; ``` 2. **空值处理**:如果允许字段为空,可以直接将其设置为 `NULL`,如 `SET hire_date = NULL`。 3. **事务控制**:建议在执行大规模更新操作前,先进行数据备份或使用事务控制(如 `BEGIN ... COMMIT;`)以避免意外的数据丢失。 4. **性能优化**:对于大型表,在没有明确条件的情况下更新整个表可能会导致性能问题,因此应谨慎操作并考虑索引和锁定机制的影响。 5. **默认值设置**:如果希望更改字段的默认值,可以通过 `ALTER TABLE` 命令实现,但这与直接更新现有数据不同 [^3]。 ### 示例代码 以下是几种常见的用法示例: #### 更新特定记录 ```sql -- 将 ID 为 100 的员工入职日期改为 '2022-05-15' UPDATE employees SET hire_date = DATE '2022-05-15' WHERE employee_id = 100; ``` #### 更新所有记录 ```sql -- 将所有员工的入职日期统一设为 '2023-01-01' UPDATE employees SET hire_date = DATE '2023-01-01'; ``` #### 使用 TO_DATE 函数处理自定义格式 ```sql -- 将生日字段设置为 '1990/08/25' UPDATE customers SET birthday = TO_DATE('1990/08/25', 'YYYY/MM/DD') WHERE customer_id = 5; ``` #### 清除某个日期字段的值 ```sql -- 清除所有 IT 部门员工的入职日期 UPDATE employees SET hire_date = NULL WHERE department = 'IT'; ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值