Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Удалить дубликаты по определенной логики  [new]
asd24
Member

Откуда:
Сообщений: 47
Добрый день.
Есть таблица Logs, которая хранит историю изменений некоторой таблицы. Стоит задача зачистить лог от дубликатов. Данные выгладят следующим образом:
ID = 1; Value = A; LogDate = 2016-05-17

ID = 2; Value = B; LogDate = 2016-05-18

ID = 3; Value = B; LogDate = 2016-05-19

ID = 4; Value = A; LogDate = 2016-05-19

ID = 5; Value = A; LogDate = 2016-05-20

ID = 6; Value = C; LogDate = 2016-05-21


После обработки должно получиться (смотрим только на Value: когда идут 2 подряд одинаковые Value - это считается дубликатом)
ID = 1; Value = A; LogDate = 2016-05-17

ID = 3; Value = B; LogDate = 2016-05-18

ID = 5; Value = A; LogDate = 2016-05-20

ID = 6; Value = C; LogDate = 2016-05-21


Можно ли как-то это реализовать?

На руках SQL Server 2008 R2 Enterprise Edition.

Спасибо.
17 май 17, 16:39    [20490513]     Ответить | Цитировать Сообщить модератору
 Re: Удалить дубликаты по определенной логики  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
asd24,

пронумеровать, удалить номера > 1
17 май 17, 16:47    [20490555]     Ответить | Цитировать Сообщить модератору
 Re: Удалить дубликаты по определенной логики  [new]
asd24
Member

Откуда:
Сообщений: 47
TaPaK
asd24,

пронумеровать, удалить номера > 1


Если я вас правильно понял, то тогда у меня в итоговой таблице будет 3 записи, а нужно чтобы было 4 (две - A, по одной - B, C).
17 май 17, 16:51    [20490584]     Ответить | Цитировать Сообщить модератору
 Re: Удалить дубликаты по определенной логики  [new]
Rankatan
Member

Откуда:
Сообщений: 250
with T as (select ROW_NUMBER() OVER(order by ID) Pos,Value from LogTable)
delete T1 from T T1 join T T2 on T1.Pos=T2.Pos-1 and T1.Value=T2.Value
17 май 17, 16:53    [20490601]     Ответить | Цитировать Сообщить модератору
 Re: Удалить дубликаты по определенной логики  [new]
asd24
Member

Откуда:
Сообщений: 47
Rankatan
with T as (select ROW_NUMBER() OVER(order by ID) Pos,Value from LogTable)
delete T1 from T T1 join T T2 on T1.Pos=T2.Pos-1 and T1.Value=T2.Value


То, что нужно! Спасибо!
17 май 17, 17:13    [20490694]     Ответить | Цитировать Сообщить модератору
 Re: Удалить дубликаты по определенной логики  [new]
Руслан Дамирович
Member

Откуда: Резиновая нерезиновая
Сообщений: 940
DECLARE @tbl TABLE (
  [ID] INT NOT NULL,
  [VALUE] CHAR(1) NOT NULL,
  [LOGDATE] DATE NOT NULL )
;
INSERT
INTO
  @tbl
VALUES
 ( 1, 'A', '20160517' ),
 ( 2, 'B', '20160518' ),
 ( 3, 'B', '20160519' ),
 ( 4, 'A', '20160519' ),
 ( 5, 'A', '20160520' ),
 ( 6, 'C', '20160521' )
;
WITH
t0 AS (
  SELECT
    [ID],
    [VALUE],
    [LOGDATE],
    [RN] = ROW_NUMBER()
           OVER (
             ORDER BY
               [ID] )
         - ROW_NUMBER()
           OVER (
             PARTITION BY
               [VALUE]
             ORDER BY
               [ID] )
  FROM
    @tbl
)
SELECT
  [ID] = MIN( [ID] ),
  [VALUE],
  [LOGDATE] = MIN( [LOGDATE] )
FROM
  t0
GROUP BY
  [VALUE],
  [RN]
ORDER BY
  1
;
17 май 17, 17:56    [20490861]     Ответить | Цитировать Сообщить модератору
 Re: Удалить дубликаты по определенной логики  [new]
asd24
Member

Откуда:
Сообщений: 47
Руслан Дамирович
DECLARE @tbl TABLE (
  [ID] INT NOT NULL,
  [VALUE] CHAR(1) NOT NULL,
  [LOGDATE] DATE NOT NULL )
;
INSERT
INTO
  @tbl
VALUES
 ( 1, 'A', '20160517' ),
 ( 2, 'B', '20160518' ),
 ( 3, 'B', '20160519' ),
 ( 4, 'A', '20160519' ),
 ( 5, 'A', '20160520' ),
 ( 6, 'C', '20160521' )
;
WITH
t0 AS (
  SELECT
    [ID],
    [VALUE],
    [LOGDATE],
    [RN] = ROW_NUMBER()
           OVER (
             ORDER BY
               [ID] )
         - ROW_NUMBER()
           OVER (
             PARTITION BY
               [VALUE]
             ORDER BY
               [ID] )
  FROM
    @tbl
)
SELECT
  [ID] = MIN( [ID] ),
  [VALUE],
  [LOGDATE] = MIN( [LOGDATE] )
FROM
  t0
GROUP BY
  [VALUE],
  [RN]
ORDER BY
  1
;


Спасибо, тоже подошло. Но вариант выше выглядит проще :)
18 май 17, 09:12    [20491727]     Ответить | Цитировать Сообщить модератору
 Re: Удалить дубликаты по определенной логики  [new]
uaggster
Member

Откуда:
Сообщений: 826
Ну, и классическое:
if OBJECT_ID('tempdb..#t') is not Null
	Drop table #t

Create table #t (ID int, [Value] char(1), LogDate date)

insert into #t Values
(1, 'A', '20160517'),
(2, 'B','20160518'),
(3, 'B','20160519'),
(4, 'A','20160519'),
(5, 'A','20160520'),
(6, 'C','20160521')

Select * from #t

;With t as (
Select ID, [Value], lag([Value]) over (order by ID) [Value_Prev]
	From #t
	)
Delete from t where [Value]=[Value_Prev]

;Select * from #t
18 май 17, 10:10    [20491942]     Ответить | Цитировать Сообщить модератору
 Re: Удалить дубликаты по определенной логики  [new]
uaggster
Member

Откуда:
Сообщений: 826
Пардон, не lag, a lead, оставляем нижний в списке дублей.
18 май 17, 10:13    [20491957]     Ответить | Цитировать Сообщить модератору
 Re: Удалить дубликаты по определенной логики  [new]
iiyama
Member

Откуда:
Сообщений: 642
uaggster,

у автора 2008r2 lag,lead c 2012-го
18 май 17, 10:24    [20491999]     Ответить | Цитировать Сообщить модератору
 Re: Удалить дубликаты по определенной логики  [new]
uaggster
Member

Откуда:
Сообщений: 826
iiyama, упс :-)
18 май 17, 11:20    [20492271]     Ответить | Цитировать Сообщить модератору
 Re: Удалить дубликаты по определенной логики  [new]
uaggster
Member

Откуда:
Сообщений: 826
iiyama
uaggster,

у автора 2008r2 lag,lead c 2012-го

Тогда так:
if OBJECT_ID('tempdb..#t') is not Null
	Drop table #t

Create table #t (ID int, [Value] char(1), LogDate date)

insert into #t Values
(1, 'A', '20160517'),
(2, 'B','20160518'),
(3, 'B','20160519'),
(4, 'A','20160519'),
(5, 'A','20160520'),
(6, 'C','20160521')

Select * from #t

Delete a
	From #t a
		Cross apply (select top (1) [Value] from #t b Where a.ID<b.ID Order by b.ID) c
Where a.[Value]=c.[Value]

;Select * from #t

Но, боюсь, милота этого запроса аж зашкаливает (по производительности).
Лучший предложил Rankatan :)
18 май 17, 12:42    [20492552]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить