我有一个表Employee,其数据类似
Employee_id | Name | M_date
------------+------+----------
1 | A | 5/1/2013
2 | B | 4/1/2014
3 | C | 7/1/2015
4 | D | 9/1/2015
5 | E | 10/1/2020
6 | X | 11/1/2019
我需要编写一个Oracle函数,它通过M_DATE
和sysdate
(今天的日期)返回员工的工作级别。
逻辑如下(伪代码跟随)
int nMonthDiff = (12 * (M_date year - Current year) + (M_date month - Current Month));
if (current year is greater than M_date year)
then employee_level = 'employee moved to other divison'
else if (nMonthDiff <= 12) THEN employee_level = 12
else if (nMonthDiff <= 24) THEN employee_level = 11
else if (nMonthDiff <= 36) THEN employee_level = 10
else if (nMonthDiff <= 48) THEN employee_level = 9
else if (nMonthDiff <= 60) THEN employee_level = 8
else employee_level = 'junior'
答案 0 :(得分:0)
因为当月份增加12时,级别代码会增加1,所以月份的整数除法将使您达到级别代码的正确比例。由于级别代码随着月数的增加而减少,因此缩放代码的减法将反转级别代码的比例。这是一个将在Postgres中执行的查询:
select
employee_id,
case when extract(year from m_date) > extract(year from now()) then 'Moved to other division'
else cast(12 - floor(abs(12 * (extract(year from m_date)-extract(year from now()))
+ (extract(month from m_date) - extract(month from now()))) / 12) as character varying)
end as level
from employee;
您必须自己适应Oracle。
答案 1 :(得分:0)
到现在为止,我想你已经为自己转换了@ rd_nielsen的答案。然而令我感到震惊的是,即使你使用的是PostGres也不太对劲,所以我给了它一个旋转。
Select
diffs.Employee_id,
diffs.emp_name,
case
when diffs.nYearDiff > 0 then 'Moved to other division'
when diffs.nMonthDiff > 60 then 'Junior'
else TO_CHAR(GREATEST(12, 12 - FLOOR(diffs.nMonthDiff / 12)))
end AS Employee_Level
FROM
(
SELECT
my_employee.Employee_id,
my_employee.emp_name,
(extract(year from m_date) - extract(year from sysdate)) as nYearDiff,
((12 * (extract(year from m_date) - extract(year from sysdate))) + (extract(month from m_date) - extract(month from sysdate))) as nMonthDiff
FROM
my_employee
) diffs
此代码借用了@ rd_nielsen的观点,即级别之间的间隔恒定为12,添加了nMonthDiff
为负时的处理(使用GREATEST
和避免ABS
),还有交易与你的“初级”类别。
你实际上要求我们作为功能,而不是查询,所以如果你正在阅读这个并且仍然想要一个功能,你可以这样打电话:level_at_date(M_Date, at_date)
或只是level(M_date)
然后做这么说,我会看看我的Oracle技能是否可以延伸到这一点。