Oracle将日期范围拆分为每日数据?新手SQL报错求助
如何将日期区间拆分为每日记录(Oracle SQL)
问题描述
我有一张名为emp_vac的表,结构和数据如下:
| From_date | To_date | EMP_Cod |
|---|---|---|
| 2013-01-01 | 2013-01-04 | 5150 |
| 2013-01-05 | 2013-01-06 | 5151 |
我想要把每个员工的假期区间拆成每日的记录,最终输出格式如下:
| Date | EMP_Cod |
|---|---|
| 2013-01-01 | 5150 |
| 2013-01-02 | 5150 |
| 2013-01-03 | 5150 |
| 2013-01-04 | 5150 |
| 2013-01-05 | 5151 |
| 2013-01-06 | 5151 |
我尝试写了一段SQL,但执行失败了:
select * FROM emp_vac; with nums as ( SELECT level-1 daystoadd form dual connect by level <= 60 ) select from_date + daystoadd thedate from emp_vac cross join nums where emp_vac.to_date - emp_vac.from_date + 1 > daystoadd and (emp_ser='5150') ;
报错信息是:
Error at Command Line:3 Column:25
我是SQL新手,希望大家能帮我找出问题并解决!
问题排查与修正方案
先看你报错的位置——第3行第25列,这里有个明显的拼写错误:form应该写成from,这是导致语法报错的直接原因。除此之外,你的SQL还有几个小问题需要调整:
- 字段名错误:你的表中存储员工编号的字段是
EMP_Cod,但你写了emp_ser='5150',这会导致字段不存在的错误,需要改成EMP_Cod='5150'(如果只需要这个员工的记录)。 - 缺失返回字段:你当前的查询只返回了日期,没有包含
EMP_Cod,不符合你想要的输出格式。 - 日期判断逻辑优化:原来的条件
emp_vac.to_date - emp_vac.from_date + 1 > daystoadd可以改成emp_vac.From_date + nums.daystoadd <= emp_vac.To_date,这样更清晰易懂,也能准确过滤掉超出假期结束日期的记录。
下面是修正后的完整SQL(处理所有员工的假期拆分):
WITH nums AS ( SELECT level - 1 AS daystoadd FROM dual CONNECT BY level <= 60 -- 60天的偏移量足够覆盖大多数短假期,需要更长区间的话可以调整这个数值 ) SELECT emp_vac.From_date + nums.daystoadd AS "Date", emp_vac.EMP_Cod FROM emp_vac CROSS JOIN nums WHERE emp_vac.From_date + nums.daystoadd <= emp_vac.To_date ORDER BY "Date", EMP_Cod;
如果只需要处理EMP_Cod=5150的员工,只需在WHERE子句末尾加上对应的过滤条件即可:
WITH nums AS ( SELECT level - 1 AS daystoadd FROM dual CONNECT BY level <= 60 ) SELECT emp_vac.From_date + nums.daystoadd AS "Date", emp_vac.EMP_Cod FROM emp_vac CROSS JOIN nums WHERE emp_vac.From_date + nums.daystoadd <= emp_vac.To_date AND emp_vac.EMP_Cod = '5150' ORDER BY "Date";
简单说明
WITH nums AS (...):生成一个包含0到59的数字序列,用来作为日期的偏移量,帮我们生成区间内的每一天。CROSS JOIN nums:把每个员工的假期记录和数字序列做笛卡尔积,这样每个假期区间就能对应到每一天的偏移量。WHERE条件:确保生成的日期不会超过假期的结束日期,避免生成无效记录。ORDER BY:让结果按日期和员工编号排序,和你想要的输出格式一致。
内容的提问来源于stack exchange,提问作者islaambahy
相关产品推荐
相关产品推荐

