Извлекать / обновлять строки с минимальным отклонением в определенном значении столбца - PullRequest
0 голосов
/ 08 октября 2009

У меня есть таблица базы данных с одним столбцом даты. Тем не менее, некоторые строки должны иметь одинаковую дату, но из-за задержки при вставке разница между ними составляет одну секунду. Часть вставки уже исправлена, но текущие данные в таблице также должны быть исправлены.

В качестве примера представлены следующие данные:

2008-10-08 12:23:01   1   1   x
2008-10-08 12:23:01   1   2   y
2008-10-08 12:23:02   1   3   z

Теперь я хочу обновить последнюю строку в этом примере и установить дату '2008-10-08 12:23:01'.

Ответы [ 4 ]

0 голосов
/ 08 октября 2009

Предположим, у вас есть эта структура:

create table tbl(id int identity, dt datetime)
insert into tbl (dt) values('2009-10-08 12:23:01')
insert into tbl (dt) values('2009-10-08 12:23:01')
insert into tbl (dt) values('2009-10-08 12:23:02')
insert into tbl (dt) values('2009-10-08 12:23:05')
insert into tbl (dt) values('2009-10-08 12:23:05')
insert into tbl (dt) values('2009-10-08 12:23:06')

Этот запрос покажет только последний элемент каждого набора, который опаздывает на 1 секунду:

select distinct A.* from tbl A
join (select * from tbl) AS T on datediff(ss, T.dt, A.dt) = 1

Используя это вместе с оператором UPDATE, вы получите следующее:

update tbl set dt = (select top 1 dt from tbl where tbl.id < A.id order by tbl.id desc)
from tbl A
join (select * from tbl) AS T on datediff(ss, T.dt, A.dt) = 1

И это обновляет последнюю запись каждого набора до даты над ней, давая результаты:

1           2009-10-08 12:23:01.000
2           2009-10-08 12:23:01.000
3           2009-10-08 12:23:01.000
4           2009-10-08 12:23:05.000
5           2009-10-08 12:23:05.000
6           2009-10-08 12:23:05.000

Он быстрый, грязный и неоптимизированный, но для разовой очистки данных должен работать.

Не забудьте сделать резервную копию!

0 голосов
/ 08 октября 2009

Лучший способ, о котором я могу думать, - это написать внешний скрипт для этого. Сложно определить, какие столбцы правильные, а какие следует обновлять, не имея больше контроля над группировкой. Псевдо-код:

all_rows = SELECT * FROM table ORDER BY date
last_date = NULL
rows_to_update = []
for row in all_rows:
    if last_date is NULL or row.date - last_date > X seconds:
        set date to last_date for all rows from rows_to_update
        last_date = row.date
        rows_to_update = []
    else if row.date != last_date:
        rows_to_update += row

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

UPDATE
   tbl t,
   (SELECT
        t.date,
        (SELECT min(date)
         FROM tbl
         WHERE timestampdiff(SECOND,date,t.date) BETWEEN 1 AND 3) AS new_date
    FROM tbl t) t2
SET t.date=t2.new_date
WHERE t.date=t2.date AND t2.new_date IS NOT NULL
0 голосов
/ 08 октября 2009

из-за задержки во вставке

Почему бы вам не получить дату вставки до вставки / обновления первой строки и использовать ее для всех остальных строк?

0 голосов
/ 08 октября 2009

Для всех строк ::.

update yourtable set  date_added=date_added-'01';

для конкретной строки добавить предложение where

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...