none
MSSQL 2008 и повторяющиеся строки RRS feed

  • Вопрос

  • Доброго всем времени суток! Т.к. мозги я себе уже сломал,пишу сюда.

    Есть таблица вида

    id    time1  time2      комментарий1      комментарий2         комментарий3

    1    ts4      ts1            загон1                  комната1                 угол1

    2    ts5      ts1            загон1                  комната1                 угол1

    3    ts6      ts1            загон1                  комната1                 угол1

    4    ts7      ts2            загон1                  комната1                 угол1

    5    ts4      ts2            загон1                  комната1                 угол1

    6    ts5      ts3            загон1                  комната1                 угол1

    необходимо выбрать строку, где time2 будет иметь различное значение,если повторяется то первое попавшее значение

    т.е. выбрать строку с id = 1,4,6

    15 августа 2012 г. 11:05

Ответы

  • declare @t table ( id int
                     , time1 char(3)
                     , time2 char(3)
                     , [комментарий1] char(6)
                     , [комментарий2] char(8)
                     , [комментарий3] char(5)
                     ); 
    insert into @t
    values ( 1, 'ts4', 'ts1', 'загон1', 'комната1', 'угол1' )
         , ( 2, 'ts5', 'ts1', 'загон1', 'комната1', 'угол1' )
         , ( 3, 'ts6', 'ts1', 'загон1', 'комната1', 'угол1' )
         , ( 4, 'ts7', 'ts2', 'загон1', 'комната1', 'угол1' )
         , ( 5, 'ts4', 'ts2', 'загон1', 'комната1', 'угол1' )
         , ( 6, 'ts5', 'ts3', 'загон1', 'комната1', 'угол1' );
    
    --1 способ
    select * from @t t1
      where not exists ( select * from @t t2 
                           where t1.time2 = t2.time2
                             and t2.id < t1.id
                       );
    
    --2 способ
    select * from @t t1
      where id <= all ( select id from @t t2 
                          where t1.time2 = t2.time2
                      );
    
    --3 способ
    with cte
    as
    (
    select row_number() over ( partition by time2 order by id ) i
         , * from @t
    )
    select id, time1, time2
         , [комментарий1]
         , [комментарий2]
         , [комментарий3] 
      from cte
      where i = 1;
    
    --4 способ
    select * from @t t
    where id = ( select min(id) from @t 
                   where time2 = t.time2
               );
    
    --5 способ
    select t1.* from @t t1
      inner join ( select min(id) id, time2 from @t
                     group by time2
                 ) t2
        on t1.id = t2.id
       and t1.time2 = t2.time2;
    
    --6 способ
    select t1.* 
      from @t t1
        left join @t t2
          on t1.time2 = t2.time2
         and t1.id > t2.id
      where t2.time2 is null;
    
    --7 способ
    select t.* from @t t
      cross apply ( select time2, min(id) id from @t
                      where time2 = t.time2
                      group by time2 
                  ) ca
      where t.id = ca.id
    
    --И ещё, ещё, ещё...


    http://www.t-sql.ru

    16 августа 2012 г. 4:59
    Модератор
  • select top 1 with ties *
    from t
    order by row_number() over( partition by time2 order by id)


    • Изменено Roman Sergeev 15 августа 2012 г. 16:53
    • Предложено в качестве ответа PashaPashModerator 15 августа 2012 г. 17:42
    • Помечено в качестве ответа Alexey KnyazevModerator 17 августа 2012 г. 4:30
    15 августа 2012 г. 16:52

Все ответы

  • select top 1 with ties *
    from t
    order by row_number() over( partition by time2 order by id)


    • Изменено Roman Sergeev 15 августа 2012 г. 16:53
    • Предложено в качестве ответа PashaPashModerator 15 августа 2012 г. 17:42
    • Помечено в качестве ответа Alexey KnyazevModerator 17 августа 2012 г. 4:30
    15 августа 2012 г. 16:52
  • declare @t table ( id int
                     , time1 char(3)
                     , time2 char(3)
                     , [комментарий1] char(6)
                     , [комментарий2] char(8)
                     , [комментарий3] char(5)
                     ); 
    insert into @t
    values ( 1, 'ts4', 'ts1', 'загон1', 'комната1', 'угол1' )
         , ( 2, 'ts5', 'ts1', 'загон1', 'комната1', 'угол1' )
         , ( 3, 'ts6', 'ts1', 'загон1', 'комната1', 'угол1' )
         , ( 4, 'ts7', 'ts2', 'загон1', 'комната1', 'угол1' )
         , ( 5, 'ts4', 'ts2', 'загон1', 'комната1', 'угол1' )
         , ( 6, 'ts5', 'ts3', 'загон1', 'комната1', 'угол1' );
    
    --1 способ
    select * from @t t1
      where not exists ( select * from @t t2 
                           where t1.time2 = t2.time2
                             and t2.id < t1.id
                       );
    
    --2 способ
    select * from @t t1
      where id <= all ( select id from @t t2 
                          where t1.time2 = t2.time2
                      );
    
    --3 способ
    with cte
    as
    (
    select row_number() over ( partition by time2 order by id ) i
         , * from @t
    )
    select id, time1, time2
         , [комментарий1]
         , [комментарий2]
         , [комментарий3] 
      from cte
      where i = 1;
    
    --4 способ
    select * from @t t
    where id = ( select min(id) from @t 
                   where time2 = t.time2
               );
    
    --5 способ
    select t1.* from @t t1
      inner join ( select min(id) id, time2 from @t
                     group by time2
                 ) t2
        on t1.id = t2.id
       and t1.time2 = t2.time2;
    
    --6 способ
    select t1.* 
      from @t t1
        left join @t t2
          on t1.time2 = t2.time2
         and t1.id > t2.id
      where t2.time2 is null;
    
    --7 способ
    select t.* from @t t
      cross apply ( select time2, min(id) id from @t
                      where time2 = t.time2
                      group by time2 
                  ) ca
      where t.id = ca.id
    
    --И ещё, ещё, ещё...


    http://www.t-sql.ru

    16 августа 2012 г. 4:59
    Модератор
  • Всем спасибо
    16 августа 2012 г. 13:00