给定当前职位代码(例如 DA123-2)和之前的职位代码(例如 DA123-1),从之前职位代码的日期开始计算任期(忽略职位代码中连字符后面的任何内容)。
在提供的示例中,员工的工作角色更改了四次:ITW124 -> DA123 -> DA123-1 -> DA123-2。由于连字符之前的最后三个职位代码相同,因此我们应该考虑截至 2024 年 3 月 23 日的最后一次职位变更。
请参阅下面的样本数据表
我们无法使用分析函数(LAG/LEAD),因为它不受支持。 我尝试在 Job_ID 上使用以前的日期,但没有成功。
从 Oracle 12 开始,您可以使用
MATCH_RECOGNIZE
执行逐行模式匹配,并从职位代码主干不变的最新角色中查找最早的日期:
WITH emp_jobs (eid, changedate, job_code) AS (
SELECT e.eid,
e.changedate,
REGEXP_REPLACE(j.job_code, '-.*$')
FROM employee e
INNER JOIN job j
ON e.job_id = j.job_id
)
SELECT eid,
TRUNC(SYSDATE) - changedate AS tenure
FROM emp_jobs
MATCH_RECOGNIZE(
PARTITION BY eid
ORDER BY changedate DESC
MEASURES
LAST(changedate) AS changedate
PATTERN ( ^ same_job+ )
DEFINE same_job AS FIRST(job_code) = job_code
)
如果您无法使用
MATCH_RECOGNIZE
或分析函数,那么您可以使用:
WITH emp_jobs (eid, changedate, job_code) AS (
SELECT e.eid,
e.changedate,
REGEXP_REPLACE(j.job_code, '-.*$')
FROM employee e
INNER JOIN job j
ON e.job_id = j.job_id
)
SELECT eid,
TRUNC(SYSDATE) - MIN(changedate) AS tenure
FROM emp_jobs ej
WHERE NOT EXISTS (
SELECT 1
FROM emp_jobs x
WHERE ej.eid = x.eid
AND ej.job_code != x.job_code
AND ej.changedate < x.changedate
)
GROUP BY eid
对于样本数据:
CREATE TABLE employee (eid, job_id, changedate) AS
SELECT 123, 1001, TRUNC(SYSDATE) - 0 FROM DUAL UNION ALL
SELECT 123, 2002, TRUNC(SYSDATE) - 37 FROM DUAL UNION ALL
SELECT 123, 3003, TRUNC(SYSDATE) - 110 FROM DUAL UNION ALL
SELECT 123, 4004, TRUNC(SYSDATE) - 150 FROM DUAL UNION ALL
SELECT 123, 3003, TRUNC(SYSDATE) - 300 FROM DUAL;
CREATE TABLE job (job_id, job_code) AS
SELECT 1001, 'DA123-2' FROM DUAL UNION ALL
SELECT 2002, 'DA123-1' FROM DUAL UNION ALL
SELECT 3003, 'DA123' FROM DUAL UNION ALL
SELECT 4004, 'ITW124' FROM DUAL;
两个输出:
开斋节 | 终身教职 |
---|---|
123 | 110 |