将每个日期范围转换为每一天的行oracle



我有一个看起来像这样的表

从_date到_date emp_cod 2013-01-01 2013-01-04 5150 2013-01-05 2013-01-06 5151

我如何像这样返回它...

     日期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

我采用了这种方法,但没有成功

    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')
;

在命令行中给我错误:3列:25

请帮助我初学者

您已发布的代码中唯一明显的错误是您有form dual而不是from dual。但是,有了这一修复的情况,它并不能给您想要的输出,因为您只得到日期,而仅适用于一名员工:

THEDATE   
----------
2013-01-01
2013-01-02
2013-01-03
2013-01-04

您可以删除过滤器并添加emp_ser值:

with nums as (
SELECT level-1 daystoadd
from dual 
connect by level <= 60
)
select from_date + daystoadd thedate, emp_ser
from emp_vac
cross join nums
where emp_vac.to_date - emp_vac.from_date + 1 > daystoadd -- and (emp_ser='5150')
order by emp_ser, thedate;
THEDATE       EMP_SER
---------- ----------
2013-01-01       5150
2013-01-02       5150
2013-01-03       5150
2013-01-04       5150
2013-01-05       5151
2013-01-06       5151

60天的硬限制有点尴尬。您可以通过一个层次查询获得相同的结果:

select from_date + level - 1 as vac_date, emp_ser
from emp_vac
connect by emp_ser = prior emp_ser
and level <= to_date - from_date + 1
and prior dbms_random.value is not null;
VAC_DATE      EMP_SER
---------- ----------
2013-01-01       5150
2013-01-02       5150
2013-01-03       5150
2013-01-04       5150
2013-01-05       5151
2013-01-06       5151

需要尴尬地调用非确定性函数(在这种情况下为dbms_random.value,但您可以使用其他功能)可以正常使用多个源行;或带有递归副问题:

with rcte (vac_date, to_date, emp_ser) as (
  select from_date, to_date, emp_ser
  from emp_vac
  union all
  select vac_date + 1, to_date, emp_ser
  from rcte
  where vac_date < to_date
)
select vac_date, emp_ser
from rcte
order by emp_ser, vac_date;
VAC_DATE      EMP_SER
---------- ----------
2013-01-01       5150
2013-01-02       5150
2013-01-03       5150
2013-01-04       5150
2013-01-05       5151
2013-01-06       5151

在这里,锚成员获得了每个记录的开始日期,递归成员一次添加一天,直到达到结束日期。(顺便说一句,我建议不要将诸如to_date之类的函数名称作为列名称 - 合法但令人困惑。)

当然,如果假期跨越了一个周末或其他假期,那么所有这些方法都将包括那些非工作日,这可能不是您想要的。不包括周末会相对简单,但是要排除其他假期,您需要一个查找桌子来识别那些日期。


正如评论中指出的@ponderstibbons所述,某些版本中有一个带有日期和递归CTE的错误(可能只有11.2.0.1和11.2.0.2-似乎是错误11840579,该错误显示为11.2.0.3在MOS中固定的固定);这是使用数字而不是递归成员限制的日期的思考的解决方法:

with rcte (rn, diff, from_date, emp_ser) as (
  select 1, trunc(to_date - from_date), from_date, emp_ser from emp_vac
  union all
  select rn + 1, diff, from_date, emp_ser from rcte where rn <= diff )
select from_date + rn - 1 vac_date, emp_ser
from rcte
order by emp_ser, vac_date;

...和db&lt;>小提琴(11.2.0.2)。

尝试此

select (from_Date+r-1), emp_code1 from (
select distinct a.from_Date,a.emp_code as emp_code1 , b.emp_code as emp_code2 , b.r from  emp_vac a,  (Select emp_code, level r
From emp_vac b  
Connect By level <= (to_Date-from_Date)+1  )  b where a.emp_code=b.emp_code
) where emp_code1=emp_code2
SELECT DISTINCT
 em_code, (to_date(end_date,'DD-MM-YYYY') - level + 1) AS days
FROM
   islaam_vca where em_code = '2222'
CONNECT BY level <= (to_date(end_date,'DD-MM-YYYY') - to_date(start_date,'DD-MM-YYYY') + 1)
order by days ASC
;

这是我测试此代码并与我合作的工作

相关内容

最新更新