如何根据数据编写Oracle函数

时间:2016-11-20 21:32:05

标签: sql oracle plsql

我有一个表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_DATEsysdate(今天的日期)返回员工的工作级别。

逻辑如下(伪代码跟随)

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'

2 个答案:

答案 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技能是否可以延伸到这一点。