我有一个看起来像这样的表
从_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
;
这是我测试此代码并与我合作的工作