SQL - Удалять дубликаты по метке времени - PullRequest
0 голосов
/ 14 июля 2020

У меня проблема в том, что есть таблица истории, которая каждый день делает выписку из таблицы и дает ей временную метку. К сожалению, в прошлом данные загружались несколько раз каждый день, чего не должно быть.

Это похоже на:

  • timestamp / id
  • 13.07.2020 15: 01 ... / 123
  • 13.07.2020 15:02 ... / 123
  • 13.07.2020 15:03 ... / 123
  • 14.07.2020 15 : 01 ... / 123
  • 14.07.2020 15:02 ... / 123
  • 14.07.2020 15:03 ... / 123

И должно быть так:

  • 13.07.2020 15:01 ... / 123
  • 14.07.2020 15:01 ... / 123

Я ищу способ удалить дубликаты на основе первой отметки времени для каждого дня.

Есть ли у вас какие-либо идеи по удалению дубликатов таким способом?

Заранее спасибо!

Ответы [ 3 ]

4 голосов
/ 14 июля 2020

Я бы рекомендовал удалить с помощью CTE:

WITH cte AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY id, CONVERT(date, ts_col) ORDER BY ts_col) rn
    FROM yourTable
)

DELETE
FROM cte
WHERE rn > 1;     -- targets all records per day except for the first one
0 голосов
/ 14 июля 2020

Вы можете использовать этот выбор для управления:

select  a.* from yourtable a
inner join
(
    select id,convert(date,[datetime]) [date], MIN([datetime]) [datetime]
    from yourtable
    group by id,convert(date,[datetime])
) b on a.id = b.id and convert(date,a.[datetime]) = b.[date] and a.[datetime] <> b.[datetime]

И удаление:

delete  a from yourtable a
inner join
(
    select id,convert(date,[datetime]) [date], MIN([datetime]) [datetime]
    from yourtable
    group by id,convert(date,[datetime])
) b on a.id = b.id and convert(date,a.[datetime]) = b.[date] and a.[datetime] <> b.[datetime]
0 голосов
/ 14 июля 2020

Если у вас только два столбца, используйте агрегацию:

select id, cmin(timestamp) as timestamp
from t
group by id, convert(date, timestamp);

Если у вас много столбцов и вы хотите получить всю строку, то row_number(), вероятно, лучший вариант:

select t.*
from (select t.*,
             row_number() over (partition by id, convert(date, timestamp) order by timestamp) as seqnum
      from t
     ) t
where seqnum = 1;
...