问题描述
我得到的下表有以下问题:
从数据集创建一个缓慢变化的维度类型 2。 EMPLOYEE 表有每个员工的日常记录。 类型 2 - 将有有效数据和到期日期。
员工 ID | 日期 | 名称 | 经理 ID |
---|---|---|---|
123 | 1-Mar | 约翰·史密斯 | 1 |
123 | 3 月 2 日 | 约翰·史密斯 | 1 |
123 | 3 月 3 日 | 约翰·史密斯 | 2 |
123 | 3 月 4 日 | 约翰·史密斯 | 3 |
123 | 5 月 5 日 | 约翰·史密斯 | 3 |
我相信我的目标表应该是这样的:
员工 ID | 名称 | 经理 ID | 生效日期 | 到期日期 |
---|---|---|---|---|
123 | 约翰·史密斯 | 1 | 1-Mar | 3 月 3 日 |
123 | 约翰·史密斯 | 2 | 3 月 3 日 | 4 月 4 日 |
123 | 约翰·史密斯 | 3 | 3 月 4 日 | 空 |
我尝试了以下查询:
SELECT employee_id,name,manager_id,CASE
WHEN LAG(manager_id) OVER() != manager_id THEN e.date
WHEN e.date = FirsT_VALUE(e.date) OVER() THEN e.date
ELSE NULL
END as "Effective Date",CASE
WHEN LEAD(manager_id) OVER() != manager_id THEN LEAD(e.date) OVER()
ELSE NULL
END as "Expiration Date"
FROM employee e
我的结果表如下:
员工 ID | 名称 | 经理 ID | 生效日期 | 到期日期 |
---|---|---|---|---|
123 | 约翰·史密斯 | 1 | 1-Mar | 空 |
123 | 约翰·史密斯 | 1 | 空 | 3 月 3 日 |
123 | 约翰·史密斯 | 2 | 3 月 3 日 | 4 月 4 日 |
123 | 约翰·史密斯 | 3 | 3 月 4 日 | 空 |
123 | 约翰·史密斯 | 3 | 空 | 空 |
有没有人知道我可以根据我迄今为止取得的成就改变查询以实现目标表的任何方式?我以某种方式只需要生成 3 个经理 ID,但不同的将不起作用。另外,我需要找到一种方法来组合每个经理 ID 的生效日期和到期日期。任何帮助都将不胜感激。
解决方法
以下内容满足您的要求,并展示了如何添加 DDL+DML。它可能有点复杂,但我看不到简化它的明显方法。
此解决方案考虑了经理可能重复的可能性。并且它并不假设每一天都会存在,所以如果缺少一天,它仍然有效。
declare @Test table (EmployeeID int,[Date] date,[Name] varchar(32),ManagerID int);
insert into @Test (EmployeeID,[Date],[Name],ManagerID)
values
(123,'1 Mar 2021','John Smith',1),(123,'2 Mar 2021','3 Mar 2021',2),'4 Mar 2021',3),'5 Mar 2021',3);
--(123,'6 Mar 2021',2);
select EmployeeId,ManagerId,MinDate
-- Use lead to get the last date of the next grouping - since it could in theory be more than one day on,lead(MinDate) over (partition by EmployeeId,[Name] order by Grouped) MaxDate
from (
-- Get the min and max dates for a given grouping
select EmployeeId,min([Date]) MinDate,max([Date]) MaxDate,Grouped
from (
select *
-- Sum the change in manager to ensure that if a manager is repeated they form a different group,sum(Lagged) over (order by Date asc) Grouped
from (
select *
-- Lag the manager to detect when it changes,case when lag(ManagerId,1,-1) over (order by [Date] asc) <> ManagerId then 1 else 0 end Lagged
from @Test
) X
) Y
group by EmployeeId,Grouped
) Z
order by EmployeeId,Grouped;
返回:
员工编号 | 姓名 | ManagerId | 最小日期 | 最大日期 |
---|---|---|---|---|
123 | 约翰·史密斯 | 1 | 2021-03-01 | 2021-03-03 |
123 | 约翰·史密斯 | 2 | 2021-03-03 | 2021-03-04 |
123 | 约翰·史密斯 | 3 | 2021-03-04 | NULL |