sql >> Base de Datos >  >> RDS >> Sqlserver

Agrupar y ordenar con excepción adicional

Esto es bastante feo, pero creo que hace lo que necesitas.

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;

En respuesta a su actualización, y suponiendo que pueda agregar algunas columnas a su tabla de ensayo:

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;