удалить записи во временных диапазонах в SQL Server - PullRequest
1 голос
/ 27 сентября 2011

У меня много временных диапазонов в таблице TimeRanges:

StartTime         EndTime
2010-01-01 06:00  2010-01-01 18:00
2010-01-01 20:00  2010-01-01 22:00
2010-01-02 06:00  2010-01-02 18:00
2010-01-02 20:00  2010-01-02 22:00
2010-01-03 06:00  2010-01-03 18:00
2010-01-03 20:00  2010-01-03 22:00
2010-01-04 06:00  2010-01-04 18:00
2010-01-04 20:00  2010-01-04 22:00
...
...
2010-02-01 06:00  2010-02-01 18:00
2010-02-01 20:00  2010-02-01 22:00
2010-02-02 06:00  2010-02-02 18:00
2010-02-02 20:00  2010-02-02 22:00
2010-02-03 06:00  2010-02-03 18:00
2010-02-03 20:00  2010-02-03 22:00
2010-02-04 06:00  2010-02-04 18:00
2010-02-04 20:00  2010-02-04 22:00
...
...
2011-01-01 06:00  2011-01-01 18:00
2011-01-01 20:00  2011-01-01 22:00
2011-01-02 06:00  2011-01-02 18:00
2011-01-02 20:00  2011-01-02 22:00
2011-01-03 06:00  2011-01-03 18:00
2011-01-03 20:00  2011-01-03 22:00
2011-01-04 06:00  2011-01-04 18:00
2011-01-04 20:00  2011-01-04 22:00
...
...
2011-02-01 06:00  2011-02-01 18:00
2011-02-01 20:00  2011-02-01 22:00
2011-02-02 06:00  2011-02-02 18:00
2011-02-02 20:00  2011-02-02 22:00
2011-02-03 06:00  2011-02-03 18:00
2011-02-03 20:00  2011-02-03 22:00
2011-02-04 06:00  2011-02-04 18:00
2011-02-04 20:00  2011-02-04 22:00

и у меня есть несколько фильтров в таблице TimeFilters:

StartTime         EndTime
2010-02-01 00:00  2010-03-01 00:00
2011-02-01 00:00  2011-03-01 00:00
2012-02-01 00:00  2012-03-01 00:00

Мне нужно удалить записи из таблицы TimeRanges, будут сохранены только те временные диапазоны, которые находятся в таблице TimeFilters.

Проще говоря, я хочу сохранить следующие записи: с 2010-02-01 00:00 до 2010-03-01 00:00, например:

2010-02-01 06:00  2010-02-01 18:00
2010-02-01 20:00  2010-02-01 22:00
2010-02-02 06:00  2010-02-02 18:00
2010-02-02 20:00  2010-02-02 22:00
2010-02-03 06:00  2010-02-03 18:00
2010-02-03 20:00  2010-02-03 22:00
2010-02-04 06:00  2010-02-04 18:00
2010-02-04 20:00  2010-02-04 22:00

с 2011-02-01 00:00 до 2011-03-01 00:00, например:

2011-02-01 06:00  2011-02-01 18:00
2011-02-01 20:00  2011-02-01 22:00
2011-02-02 06:00  2011-02-02 18:00
2011-02-02 20:00  2011-02-02 22:00
2011-02-03 06:00  2011-02-03 18:00
2011-02-03 20:00  2011-02-03 22:00
2011-02-04 06:00  2011-02-04 18:00
2011-02-04 20:00  2011-02-04 22:00

Теперь я могу выбрать те записи, которые находятся внутри TimeFilters, во временную таблицу, затем обрезать таблицу TimeRanges и вернуть записи из временной таблицы, но это довольно много времени.

Ответы [ 3 ]

3 голосов
/ 27 сентября 2011

Чтобы удалить все записи в TimeRanges, у которых нет совпадений в TimeFilters, вы можете сделать

delete TimeRanges
  from TimeRanges r
  left join timefilters f on r.StartTime >= f.StartTime and r.EndTime <= f.EndTime 
 where f.StartTime is null

Сложнее сделать left join и удалить их.TimeRanges, которые не имеют соответствующего фильтра (когда f.startTime или f.endTime равны нулю)

После удаления вы можете увидеть результаты:

select *
  from TimeRanges

StartTime               EndTime
----------------------- -----------------------
2010-02-01 06:00:00.000 2010-02-01 18:00:00.000
2010-02-01 20:00:00.000 2010-02-01 22:00:00.000
2010-02-02 06:00:00.000 2010-02-02 18:00:00.000
2010-02-02 20:00:00.000 2010-02-02 22:00:00.000
2010-02-03 06:00:00.000 2010-02-03 18:00:00.000
2010-02-03 20:00:00.000 2010-02-03 22:00:00.000
2010-02-04 06:00:00.000 2010-02-04 18:00:00.000
2010-02-04 20:00:00.000 2010-02-04 22:00:00.000
2011-02-01 06:00:00.000 2011-02-01 18:00:00.000
2011-02-01 20:00:00.000 2011-02-01 22:00:00.000
2011-02-02 06:00:00.000 2011-02-02 18:00:00.000
2011-02-02 20:00:00.000 2011-02-02 22:00:00.000
2011-02-03 06:00:00.000 2011-02-03 18:00:00.000
2011-02-03 20:00:00.000 2011-02-03 22:00:00.000
2011-02-04 06:00:00.000 2011-02-04 18:00:00.000
2011-02-04 20:00:00.000 2011-02-04 22:00:00.000

(16 row(s) affected)
1 голос
/ 27 сентября 2011

Я полагаю, у вас есть какой-то столбец идентификаторов в вашей таблице TimeRanges?Если это так, будет ли что-то подобное для вас?

DELETE
    TimeRanges
WHERE
    id NOT IN ( SELECT
                    tr.id
                FROM
                    TimeRanges tr
                    JOIN TimeFilter tf ON tr.startdate >= tf.startdate AND
                                           tr.enddate <= tf.enddate )
1 голос
/ 27 сентября 2011

То, что вы можете сделать, - это внешнее соединение, чтобы получить как совпадения, так и несоответствия, а затем иметь условие для извлечения несоответствий:

select * form TimeRanges r join TimeFilters f on
    r.StartTime between f.StartTime and f.EndTime and
    r.EndTime between f.StartTime and f.EndTime
where f.StartTime is null and f.EndTime is null

Я не знаю, есть ли остальныеэто можно сделать с помощью MySQL, но вам нужно создать условие, соответствующее каждой строке, которая не попадала между датами в таблице фильтров.Для этого псевдокод будет выглядеть следующим образом:

cond='';

while (r = read row) do
    if (cond=='') {
        sep='';
    } else {
        sep=' OR ';
    }

    cond = cond . sep .
        '(r.StartDate=' . r->StartDate . ' and r.EndDate=' . r->EndDate . ')';
}

# Before running the delete query comment it out and run the query printed by:
#  print 'select * from TimeRanges where '.cond;
run query 'delete from TimeRanges where '.cond;

Если это невозможно сделать с помощью MySql, то это можно сделать с помощью языка сценариев, такого как PHP.

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