[英]How to get first change of column for a row in Oracle table through SQL?
维度表类型 2 记录行随时间的变化 (SCD)。 我想根据另一列说日期找到列的第一个值更改(应该是常见模式)。
例如,带有 (emp_id, insert_date, status, address) 的员工表,其中状态指示工作、不工作、假期等(一些固定值)。 比如说,这家奇怪的公司每天都在密切关注员工。 现在我想知道员工在过去一年的最后一个假期是什么时候开始的。 以下将不起作用
select distinct empid, max(insert_date) where status = 'vacation'
where insert_date > today - 1 year --- know not correct syntax but to simplify
group by empid
因为它会选择状态为假期的最后一条记录,但可能有许多带有假期的记录,因为记录可能由于地址更改等其他原因而发生更改,例如:
emp_id insert_dt status address
1 9/1/2019 working 123
1 9/2/2019 working 1234
1 9/3/2019 vacation 1234
1 9/4/2019 vacation 12345 --- address change
1 9/5/2019 working 12345
所以我想第一次发生从工作到假期的转变,这是 9/3(不是 9/4),而 min 也不起作用。
我们不能更改表架构,PL/SQL 也不能使用嵌入某些编程语言等的 SQL,只是普通的 SQL。 如果您知道 Oracle 中的任何(分析)function 可以运行 lambda 或使用编码列等模仿它,那将是理想的。
谢谢小号
使用lag()
:
select t.*
from (select t.*,
lag(status) over (partition by emp_id order by insert_dt) as prev_status
from t
) t
where status = 'vacation' and
(prev_status <> status or prev_status is null);
编辑:
如果您想要员工的最近时间,您可以使用聚合:
select emp_id, max(insert_dt)
from (select t.*,
lag(status) over (partition by emp_id order by insert_dt) as prev_status
from t
) t
where status = 'vacation' and
(prev_status <> status or prev_status is null)
group by emp_id;
您也可以在特定时间段内添加过滤。
所以我想第一次发生从工作到度假的转变
我将首先使用lag()
来获取每个emp_id
的先前状态,按insert_dt
排序。 然后,识别状态从工作切换到休假的记录,并按每个员工的insert_dt
对它们进行排名。 最后,过滤每个员工的第一条记录:
select e.*
from (
select
e.*,
row_number() over(partition by emp_id order by insert_dt) rn
from (
select
e.*,
lag(status) over(partition by emp_id order by insert_dt) lag_status
from employee e
where insert_date > add_months(trunc(sysdate), -12)
) e
where lag_status = 'working' and status = 'vacation'
) e
where rn = 1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.