请您查看以下任务?
我有以下数据集:
以下是此数据的脚本:
;with dataset AS (
select 'EMP01' AS EMP_ID,CAST('2018-01-01' AS DATE) AS PERIOD_START,CAST('2018-01-31' AS DATE) AS PERIOD_END,CAST('2018-01-07' AS DATE) AS CUT_DATE
UNION
select 'EMP01' AS EMP_ID,CAST('2018-01-01' AS DATE) AS PERIOD_START,CAST('2018-01-31' AS DATE) AS PERIOD_END,CAST('2018-01-15' AS DATE) AS CUT_DATE
UNION
select 'EMP02' AS EMP_ID,CAST('2018-01-01' AS DATE) AS PERIOD_START,CAST('2018-01-31' AS DATE) AS PERIOD_END,CAST('2018-01-09' AS DATE) AS CUT_DATE
)
select *
from dataset
我需要将这些期间(PERIOD_START和PERIOD_END)除以CUT_DATE(不包括那些期间的截止日期)切割日期的数量可以是任意的(3,5,8等)。
期望上述数据集的结果是:
答案 0 :(得分:0)
这是你需要的吗?
with dataset AS (
select 'EMP01' AS EMP_ID,CAST('2018-01-01' AS DATE) AS PERIOD_START,CAST('2018-01-31' AS DATE) AS PERIOD_END,CAST('2018-01-07' AS DATE) AS CUT_DATE
UNION
select 'EMP01' AS EMP_ID,CAST('2018-01-01' AS DATE) AS PERIOD_START,CAST('2018-01-31' AS DATE) AS PERIOD_END,CAST('2018-01-15' AS DATE) AS CUT_DATE
UNION
select 'EMP02' AS EMP_ID,CAST('2018-01-01' AS DATE) AS PERIOD_START,CAST('2018-01-31' AS DATE) AS PERIOD_END,CAST('2018-01-09' AS DATE) AS CUT_DATE
)
select emp_id, period_start period_start, cut_date - 1 period_end from dataset
union all
select emp_id, cut_date + 1 period_start, period_end period_end from dataset;
答案 1 :(得分:0)
这可以使用日期表和窗口函数来实现。如果您没有日期表,则可以使用下面脚本中的前两个cte
表为此查询生成一个:
declare @t table(emp_id nvarchar(10)
,period_start date
,period_end date
,cut_date date
);
insert into @t values
('EMP01','20180101','20180131','2018-01-07')
,('EMP01','20180101','20180131','2018-01-15')
,('EMP02','20180101','20180131','2018-01-09')
;
declare @s date = (select min(period_start) as d from @t);
declare @e date = (select max(period_end) as d from @t);
-- Generate a table of 10 rows
with t(t) as (select 1 union all select 1 union all select 1 union all select 1 union all select 1 union all select 1 union all select 1 union all select 1 union all select 1 union all select 1)
,d(d) as (select top (select datediff(day,@s,@e)+1) dateadd(day,row_number() over (order by (select null))-1,@s) from t t1,t t2,t t3,t t4,t t5) -- CROSS JOIN 10 rows together 5 times for a maximum of 10*10*10*10*10 = 100,000 rows
,c as (select d.d
,t.emp_id
,t.period_start
,t.period_end
,sum(case when t.cut_date = d.d then 1 else 0 end) over (partition by t.emp_id order by d.d) as p
from @t as t
left join d
on(d.d between t.period_start and t.period_end)
)
select emp_id
,min(case when period_start = d then d else dateadd(day,1,d) end) as period_start
,max(d) as period_end
from c
group by emp_id
,p
order by emp_id
,period_start
输出:
+--------+--------------+------------+
| emp_id | period_start | period_end |
+--------+--------------+------------+
| EMP01 | 2018-01-01 | 2018-01-06 |
| EMP01 | 2018-01-08 | 2018-01-14 |
| EMP01 | 2018-01-16 | 2018-01-31 |
| EMP02 | 2018-01-01 | 2018-01-08 |
| EMP02 | 2018-01-10 | 2018-01-31 |
+--------+--------------+------------+