问题
I have following table:
Declare @YourTable table ([Event] varchar(100),[Start] DateTime,[End] DateTime, [Tag] varchar(25))
Insert Into @YourTable values
('10PIC700422.PV 10-PSV-700073A 10-PSV-700073B','9/9/16 10:44','9/9/16 10:49','Big'),
('10PIC700422.PV 10-PSV-700073A 10-PSV-700073B','9/9/16 10:50','9/9/16 10:51','Small'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 12:51','4/4/16 13:58','Big'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 14:04','4/4/16 14:29','Small'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 14:51','4/4/16 14:58','Big'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 15:04','4/4/16 15:29','Small'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4-4-16 15:45','4-4-16 15:55','Big'),
('11PIC41010.PV 11-PSV-401002W 11-PSV-401002D','4/4/16 16:04','4/4/16 16:45','Big')
And use following query to get result I need, group by event and order by start, and change big to small whenever small goes after big:
Select [Event]
,[Start]
,[End]
,[Tag]
,[Tag_new] = case when Tag='Big' and 'Small' = Lead(Tag,1,Tag) over (Partition By Event Order By Start) then 'Small' else tag end
From @YourTable
Event Start End Tag Tag_new
10PIC700422.PV 10-PSV-700073A 10-PSV-700073B 9-9-16 10:44 9-9-16 10:49 Big Small
10PIC700422.PV 10-PSV-700073A 10-PSV-700073B 9-9-16 10:50 9-9-16 10:51 Small Small
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 4-4-16 12:51 4-4-16 13:58 Big Small
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 4-4-16 14:04 4-4-16 14:29 Small Small
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 4-4-16 14:51 4-4-16 14:58 Big Small
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 4-4-16 15:04 4-4-16 15:29 Small Small
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 4-4-16 15:45 4-4-16 15:55 Big Big
11PIC41010.PV 11-PSV-401002W 11-PSV-401002D 4-4-16 16:04 4-4-16 16:45 Big Big
but I need to apply one more exception whenever sequence below appears in Tag column in a group, Tag_new column should be "Small2" starting from Big till next Big in Tag column:
Small
Big
Small
and I'd like to get result below:
Event Start End Tag Tag_new
10PIC700422.PV 10-PSV-700073A 10-PSV-700073B 9-9-16 10:44 9-9-16 10:49 Big Small
10PIC700422.PV 10-PSV-700073A 10-PSV-700073B 9-9-16 10:50 9-9-16 10:51 Small Small
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 4-4-16 12:51 4-4-16 13:58 Big Small
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 4-4-16 14:04 4-4-16 14:29 Small Small
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 4-4-16 14:51 4-4-16 14:58 Big Small2
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 4-4-16 15:04 4-4-16 15:29 Small Small2
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 4-4-16 15:45 4-4-16 15:55 Big Big
11PIC41010.PV 11-PSV-401002W 11-PSV-401002D 4-4-16 16:04 4-4-16 16:45 Big Big
Updates to iamdave:
When I have few more small after big then it makes second small after Big just Small while should Small2 so it should be Small2 till next Big:
Declare @YourTable table ([Event] varchar(100),[Start] DateTime,[End] DateTime, [Tag] varchar(25))
Insert Into @YourTable values
('10PIC700422.PV 10-PSV-700073A 10-PSV-700073B','9/9/16 10:44','9/9/16 10:49','Big'),
('10PIC700422.PV 10-PSV-700073A 10-PSV-700073B','9/9/16 10:50','9/9/16 10:51','Small'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 12:51','4/4/16 13:58','Big'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 14:04','4/4/16 14:29','Small'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 14:51','4/4/16 14:58','Big'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 15:04','4/4/16 15:29','Small'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 15:30','4/4/16 15:32','Small'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4-4-16 15:45','4-4-16 15:55','Big'),
('11PIC41010.PV 11-PSV-401002W 11-PSV-401002D','4/4/16 16:04','4/4/16 16:45','Big')
And here is output in case few more small after Big:
Event Start End Tag Tag_new
10PIC700422.PV 10-PSV-700073A 10-PSV-700073B 9-9-16 10:44 9-9-16 10:49 Big Small
10PIC700422.PV 10-PSV-700073A 10-PSV-700073B 9-9-16 10:50 9-9-16 10:51 Small Small
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 4-4-16 12:51 4-4-16 13:58 Big Small
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 4-4-16 14:04 4-4-16 14:29 Small Small
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 4-4-16 14:51 4-4-16 14:58 Big Small2
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 4-4-16 15:04 4-4-16 15:29 Small Small2
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 4-4-16 15:30 4-4-16 15:32 Small Small
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 4-4-16 15:45 4-4-16 15:55 Big Big
11PIC41010.PV 11-PSV-401002W 11-PSV-401002D 4-4-16 16:04 4-4-16 16:45 Big Big
and it should be like below:
Event Start End Tag Tag_new
10PIC700422.PV 10-PSV-700073A 10-PSV-700073B 9-9-16 10:44 9-9-16 10:49 Big Small
10PIC700422.PV 10-PSV-700073A 10-PSV-700073B 9-9-16 10:50 9-9-16 10:51 Small Small
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 4-4-16 12:51 4-4-16 13:58 Big Small
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 4-4-16 14:04 4-4-16 14:29 Small Small
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 4-4-16 14:51 4-4-16 14:58 Big Small2
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 4-4-16 15:04 4-4-16 15:29 Small Small2
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 4-4-16 15:30 4-4-16 15:32 Small Small2
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 4-4-16 15:45 4-4-16 15:55 Big Big
11PIC41010.PV 11-PSV-401002W 11-PSV-401002D 4-4-16 16:04 4-4-16 16:45 Big Big
Updates @iamdave: sorry again for this confusion, it seems changing to small2 was wrong direction since if I have few sequence below it gives small2 for all while I was looking for separate them:
Small
Big
Small
Small
Big
Small
This is what I get:
Event Start End Tag Tag_new
10PIC700422.PV 10-PSV-700073A 10-PSV-700073B 2016-09-09 10:44:05.000 2016-09-09 10:48:08.000 Big Big
10PIC700422.PV 10-PSV-700073A 10-PSV-700073B 2016-09-09 10:44:10.000 2016-09-09 10:49:40.000 Big Small
10PIC700422.PV 10-PSV-700073A 10-PSV-700073B 2016-09-09 10:50:03.000 2016-09-09 10:51:04.000 Small Small
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 2016-04-04 12:51:07.000 2016-04-04 13:58:09.000 Big Small
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 2016-04-04 14:04:04.000 2016-04-04 14:29:00.000 Small Small
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 2016-04-04 14:51:02.000 2016-04-04 14:58:00.000 Big Small2
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 2016-04-04 15:04:06.000 2016-04-04 15:29:08.000 Small Small2
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 2016-04-04 15:45:08.000 2016-04-04 15:55:09.000 Big Small2
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 2016-04-04 16:22:08.000 2016-04-04 16:40:09.000 Small Small2
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 2016-04-04 16:50:04.000 2016-04-04 16:55:00.000 Small Small2
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 2016-04-04 17:05:02.000 2016-04-04 17:20:00.000 Big Small2
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 2016-04-04 17:22:06.000 2016-04-04 17:29:08.000 Small Small2
11PIC41010.PV 11-PSV-401002W 11-PSV-401002D 2016-04-04 16:04:01.000 2016-04-04 16:45:00.000 Big Big
So the best solution would be add additional row as I described in my recent question:
Thanks in advance for assistance, S
回答1:
This is pretty ugly, but I think it does what you need it to?
Declare @YourTable table ([Event] varchar(100),[Start] DateTime,[End] DateTime, [Tag] varchar(25))
Insert Into @YourTable values
('10PIC700422.PV 10-PSV-700073A 10-PSV-700073B','9/9/16 10:44','9/9/16 10:48','Big'),
('10PIC700422.PV 10-PSV-700073A 10-PSV-700073B','9/9/16 10:44','9/9/16 10:49','Big'),
('10PIC700422.PV 10-PSV-700073A 10-PSV-700073B','9/9/16 10:50','9/9/16 10:51','Small'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 12:51','4/4/16 13:58','Big'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 14:04','4/4/16 14:29','Small'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 14:51','4/4/16 14:58','Big'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 15:04','4/4/16 15:29','Small'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4-4-16 15:45','4-4-16 15:55','Big'),
('11PIC41010.PV 11-PSV-401002W 11-PSV-401002D','4/4/16 16:04','4/4/16 16:45','Big');
Select [Event]
,[Start]
,[End]
,[Tag]
,[Tag_new] = case when Tag = 'Big'
and Lead(Tag,1,'') over (Partition By Event
Order By Start
)
= 'Small'
then 'Small'
else tag
end
,[Tag_new2] = case when (Tag = 'Big'
and lag(Tag,1,'') over (Partition By Event
Order By Start
)
= 'Small'
and Lead(Tag,1,'') over (Partition By Event
Order By Start
)
= 'Small'
)
or (Tag = 'Small'
and lag(Tag,2,'') over (Partition By Event
Order By Start
)
= 'Small'
and lag(Tag,1,'') over (Partition By Event
Order By Start
)
= 'Big'
)
then 'Small2'
else case when Tag = 'Big'
and Lead(Tag,1,'') over (Partition By Event
Order By Start
)
= 'Small'
then 'Small'
else tag
end
end
From @YourTable;
In response to your update, and assuming you can add some columns to your Staging table:
Declare @YourTable table (EventRN int, StartRN int, MaxStartRN int, [Event] varchar(100),[Start] DateTime,[End] DateTime, [Tag] varchar(25), [TagNext] varchar(25))
Insert Into @YourTable values
(null,null,null,'10PIC700422.PV 10-PSV-700073A 10-PSV-700073B','9/9/16 10:44','9/9/16 10:49','Big',null),
(null,null,null,'10PIC700422.PV 10-PSV-700073A 10-PSV-700073B','9/9/16 10:50','9/9/16 10:51','Small',null),
(null,null,null,'11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 12:51','4/4/16 13:58','Big',null),
(null,null,null,'11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 14:04','4/4/16 14:29','Small',null),
(null,null,null,'11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 14:51','4/4/16 14:58','Big',null),
(null,null,null,'11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 15:04','4/4/16 15:29','Small',null),
(null,null,null,'11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 15:30','4/4/16 15:32','Small',null),
(null,null,null,'11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4-4-16 15:45','4-4-16 15:55','Big',null),
(null,null,null,'11PIC41010.PV 11-PSV-401002W 11-PSV-401002D','4/4/16 16:04','4/4/16 16:45','Big',null);
update t
set EventRN = tt.EventRN
,StartRN = tt.StartRN
,MaxStartRN = tt.MaxStartRN
,TagNext = tt.TagNext
from @YourTable t
inner join (
select dense_rank() over (order by Event
) as EventRN
,row_number() over (partition by Event
order by Start
) as StartRN
,count(1) over (partition by Event) as MaxStartRN
,[Event]
,[Start]
,[End]
,[Tag]
,lead(Tag,1,null) over (partition by Event
order by Start
)
as TagNext
from @YourTable
) tt
on(t.[Event] = tt.[Event]
and t.[Start] = tt.[Start]
and t.[End] = tt.[End]
and t.Tag = tt.Tag
);
with cte as
(
select EventRN
,StartRN
,MaxStartRN
,[Event]
,[Start]
,[End]
,Tag
,TagNext
,cast(null as varchar(25)) as TagPrev
,case when TagNext = 'Small'
then TagNext
else Tag
end as TagNew
from @YourTable
where EventRN = 1
and StartRN = 1
union all
select t.EventRN
,t.StartRN
,t.MaxStartRN
,t.[Event]
,t.[Start]
,t.[End]
,t.Tag
,t.TagNext
,case when t.EventRN = c.EventRN then c.Tag else null end as TagPrev
,case when t.EventRN = c.EventRN and c.Tag = 'Small' and t.Tag = 'Big' and t.TagNext = 'Small'
or t.EventRN = c.EventRN and c.TagNew = 'Small2' and t.Tag = 'Small'
then 'Small2'
else case when t.TagNext = 'Small'
then t.TagNext
else t.Tag
end
end
from cte c
inner join @YourTable t
on((c.StartRN < c.MaxStartRN
and t.EventRN = c.EventRN
and t.StartRN = c.StartRN+1
)
or (c.StartRN = c.MaxStartRN
and t.EventRN = c.EventRN+1
and t.StartRN = 1
)
)
)
select [Event]
,[Start]
,[End]
,Tag
,TagNew
from cte
order by Event
,Start;
来源:https://stackoverflow.com/questions/40026002/group-and-order-with-additional-exception