My dataset looks like this and I need to generate the StartDate (Min), EndDate(Min) by grouping them by Name and Date columns. When Type changes, the group by logic should break and take Max date till there.
| Name | Type | Date |
|---|---|---|
| A | xx | 1/1/2018 |
| A | xx | 1/2/2018 |
| A | yy | 1/3/2018 |
| A | xx | 1/4/2018 |
| A | xx | 1/5/2018 |
| A | xx | 1/6/2018 |
The output would be like:
| Name | Type | StartDate | EndDate |
|---|---|---|---|
| A | xx | 1/1/2018 | 1/2/2018 |
| A | yy | 1/3/2018 | 1/3/2018 |
| A | xx | 1/4/2018 | 1/6/2018 |
CodePudding user response:
Hope this clarify you.
select Name,Type,min(date) as StartDate,max(date) as EndDate
from Table_Name
group by Type,Name
CodePudding user response:
The challenge in this case is to identify all target groups by the columns Name and Type taking into account the gaps. As a possible solution, you can use an additional grouping expression based on the difference between Row_Number ordered by Date and Row_Number ordered by Date with Partion by Name, Type.
With A As (
Select Name, [Type], [Date],
Row_Number() Over (Order by [Date]) As Num,
Row_Number() Over (Partition by Name, [Type] Order by [Date]) As Num_1
From Tbl)
Select Name, [Type], Min([Date]) As StartDate, Max([Date]) As EndDate
From A
Group by Name, [Type], Num - Num_1
CodePudding user response:
Below approach would be bit clumsy yet fetches the desired output. The buckets are partitioned based on the date (day) difference.
declare @tbl table(name varchar(5),type varchar(5),[date] date)
insert into @tbl
values('A','xx','1/1/2018')
,('A','xx','1/2/2018')
,('A','yy','1/3/2018')
,('A','xx','1/4/2018')
,('A','xx','1/5/2018')
,('A','xx','1/6/2018')
select distinct name,type
,min(date)over(partition by name,type,diffmodified order by diffmodified) as [StartDate]
,max(date)over(partition by name,type,diffmodified order by diffmodified) as [EndDate]
from(
select *
,case when max(diff)over(partition by name,type order by [date]) > 1
then max(diff)over(partition by name,type order by [date]) else diff end as [diffmodified]
from(
select *,
isnull(DATEDIFF(day, lag([date],1)
over(partition by name,type order by [date]), [date] ),1)[diff]
from
@tbl)
t)t
