Oracle专家您好,我对如何正确连接两个表有疑问。
我的第一个表格描述了休假类别,新的最大假期休假累计额所需的最短服务时间以及最大累计数。
PTRLVAC_LCAT_CODE PTRLVAC_YEAR PTRLVAC_ROLL_MAX_HRS
C1 0 80
C1 2 88
C1 5 128
P3 0 120
P3 2 128
P3 5 168
下表详细列出了员工ID,雇用日期和休假类别
PEBEMPL_PIDM PEBEMPL_HIRE_DATE PEBEMPL_LCAT_CODE
1234 01/09/2017 P3
3214 02/01/2014 C1
我现在拥有的联接依赖CTE,我不确定这是否是最简单的解决方案。 **我已将此处的表格列为CTE
with ptrlvac as(
select 'C1' ptrlvac_lcat_code
,0 ptrlvac_year
,80 ptrlvac_roll_max_hrs
from dual union all
select 'C1', 2, 88 from dual union all
select 'C1', 5, 128 from dual union all
select 'P3', 0, 120 from dual union all
select 'P3', 5, 128 from dual union all
select 'P3', 2, 168 from dual
) , pebempl as(
select 1234 pebempl_pidm
,to_date('09-JAN-2017', 'DD-MON-YYYY') pebempl_hire_date
,'P3' pebempl_lcat_code
from dual
UNION ALL
select 3214, to_date('01-FEB-2014','DD-MON-YYYY'), 'C1' from dual
) ,leave as(
select a.ptrlvac_lcat_code
,a.ptrlvac_year
,a.ptrlvac_roll_max_hrs
,row_number()
over(partition by a.ptrlvac_lcat_code
order by a.ptrlvac_year) rn
from ptrlvac a
)
,leave_rules as(
select a.ptrlvac_lcat_code
,a.ptrlvac_year year_start
,nvl(b.ptrlvac_year, 100)-1 year_end
,a.ptrlvac_roll_max_hrs
from leave a
left join leave b
on a.ptrlvac_lcat_code = b.ptrlvac_lcat_code
and a.rn = b.rn - 1
)
select distinct pebempl_pidm
,pebempl_hire_date
,floor(months_between(to_date(:seldate, 'DD-MON-YYYY'), pebempl_hire_date) / 12) as service_years
,pebempl_lcat_code as lcat
,b.ptrlvac_roll_max_hrs
from pebempl a
inner join leave_rules b
on a.pebempl_lcat_code = b.ptrlvac_lcat_code
and floor(months_between(to_date(:seldate, 'DD-MON-YYYY'), pebempl_hire_date) / 12) between b.year_start and b.year_end
任何帮助您保存一些按键的帮助将不胜感激。
谢谢。
答案 0 :(得分:1)
我不确定这是否满足您的要求:
select
t2.PEBEMPL_PIDM,
t1.PTRLVAC_ROLL_MAX_HRS
from test1 t1, test2 t2
where
t1.PTRLVAC_LCAT_CODE = t2.PEBEMPL_LCAT_CODE and
t1.PTRLVAC_YEAR =
(select max(t1s.PTRLVAC_YEAR) from test1 t1s
where t1s.PTRLVAC_LCAT_CODE = t2.PEBEMPL_LCAT_CODE
and (sysdate-PEBEMPL_HIRE_DATE)/365 >= t1s.PTRLVAC_YEAR);
以下是我根据您的测试数据得出的结果:
PEBEMPL_PIDM PTRLVAC_ROLL_MAX_HRS
------------ --------------------
3214 88
1234 120
鲍比
答案 1 :(得分:1)
在午餐时有这种想法,进一步减少了@BobbyDurret的答案:
select
t2.PEBEMPL_PIDM,
max(t1.PTRLVAC_ROLL_MAX_HRS)
from ptrlvac t1, pebempl t2
where
t1.PTRLVAC_LCAT_CODE = t2.PEBEMPL_LCAT_CODE and
(sysdate-PEBEMPL_HIRE_DATE)/365 >= t1.PTRLVAC_YEAR
group by t2.PEBEMPL_PIDM
假设Max_Hrs在使用多年后始终会增加。
答案 2 :(得分:0)
使用Lead:代替在单独的CTE中使用row_number和过滤:
with leave_rules as
(
select a.ptrlvac_lcat_code
,a.ptrlvac_year as year_start
,a.ptrlvac_roll_max_hrs
,lead(ptrlvac_year,1,10000) over (partition by ptrlvac_lcat_code
order by ptrlvac_year)
as year_end
from ptrlvac a
)
select distinct pebempl_pidm
,pebempl_hire_date
,floor(months_between(sysdate, pebempl_hire_date) / 12) as service_years
,pebempl_lcat_code as lcat
,b.ptrlvac_roll_max_hrs
from pebempl a
inner join leave_rules b
on a.pebempl_lcat_code = b.ptrlvac_lcat_code
and floor(months_between(sysdate, pebempl_hire_date) / 12) between year_start and year_end
将您的2个CTE组合为1,以计算“ leave_rules”。我只将sysdate用作date变量,以便我可以轻松地进行测试-您可能希望像原来一样使用绑定变量。