我有一张看起来像这样的桌子
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
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上给我错误
请帮助我是新手
答案 0 :(得分:1)
您发布的代码中唯一明显的错误是您拥有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
,但您可以使用其他函数)来正确处理多个源行;或使用recursive subquery factoring:
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,已在MoS中的11.2.0.3中得到了修复。 );这是Ponder的变通办法,使用数字代替日期作为递归成员限制:
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<>fiddle(11.2.0.2)。
答案 1 :(得分:0)
尝试
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
答案 2 :(得分:0)
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
;
我正在测试此代码并与我一起工作