A Microsoft extension to the ANSI SQL language that includes procedural programming, local variables, and various support functions.
Please also check:
CREATE TABLE #test(
id INT,
area VARCHAR(100),
strt_dt DATE,
end_dt DATE,
daily_dt DATE
)
GO
INSERT #test(id,area,strt_dt,end_dt,daily_dt)
select 101 as id, 'abc' as area,'2021-01-07' as strt_dt,'2021-01-07' as end_dt, '2021-01-07' as daily_dt
union
select 101 as id, 'abc' as area, '2021-01-07' as strt_dt, '2021-01-08' as end_dt, '2021-01-07' as daily_dt
union
select 101 as id, 'mno' as area,'2021-01-08' as strt_dt,'2021-01-15' as end_dt, '2021-01-08' as daily_dt
union
select 101 as id, NULL as area,NULL as strt_dt,NULL as end_dt, '2021-01-09' as daily_dt
union
select 101 as id, NULL as area,NULL as strt_dt,NULL as end_dt, '2021-01-10' as daily_dt
union
select 101 as id, NULL as area,NULL as strt_dt,NULL as end_dt, '2021-01-11' as daily_dt
union
select 101 as id, NULL as area,NULL as strt_dt,NULL as end_dt, '2021-01-12' as daily_dt
union
select 101 as id, NULL as area,NULL as strt_dt,NULL as end_dt, '2021-01-13' as daily_dt
union
select 101 as id, NULL as area,NULL as strt_dt,NULL as end_dt, '2021-01-14' as daily_dt
union
select 101 as id, 'tt' as area,'2021-01-15' as strt_dt, '2021-01-17' as end_dt, '2021-01-15' as daily_dt
union
select 101 as id, NULL as area,NULL as strt_dt,NULL as end_dt, '2021-01-16' as daily_dt
union
select 101 as id, NULL as area,NULL as strt_dt,NULL as end_dt, '2021-01-17' as daily_dt
GO
SELECT * FROM #test
;WITH cte
as(SELECT id,area,MAX(val) ma,MIN(val) mi FROM
(SELECT * FROM #test
unpivot (val for dt in (strt_dt,end_dt,daily_dt)) as t
WHERE area is not null) u
GROUP BY id,area)
SELECT t.id,c.area,CASE WHEN t.area is not null and t.area<>c.area
and c.area <>'abc' and t.daily_dt<>'2021-01-08'
THEN NULL
WHEN c.area ='abc' and t.daily_dt='2021-01-08'
THEN t.daily_dt
ELSE t.strt_dt END strt_dt,
CASE WHEN t.area is not null and t.area<>c.area
and c.area <>'abc' and t.daily_dt<>'2021-01-08'
THEN NULL
WHEN c.area ='abc' and t.daily_dt='2021-01-08'
THEN t.daily_dt
ELSE t.end_dt END end_dt,t.daily_dt
FROM #test t
LEFT JOIN cte c ON c.id=t.id AND c.area=t.area OR t.daily_dt BETWEEN mi AND ma
ORDER BY c.area,t.daily_dt
Output:
If you have any question, please feel free to let me know.
Regards
Echo
If the answer is helpful, please click "Accept Answer" and upvote it.