У меня есть таблица примерно так:
CREATE TABLE mytable (
id INT(10) auto_increment PRIMARY KEY,
from DATE(10) NOT NULL,
before DATE(10) NULL,
reference_id INT(10) NOT NULL,
)
Итак, есть строки, которые ссылаются на другую таблицу (с reference_id
). Эти ссылки имеют диапазон дат (from
/ before
), в котором они применимы. Для каждого reference_id
может быть много записей, в которых обычно нет пробелов:
id | from | before | reference_id
-------------------------------------------
1 | 2019-03-01 | 2019-03-05 | 5
5 | 2019-03-05 | 2019-03-09 | 5
8 | 2019-03-09 | NULL | 5
(Между ними могут быть записи для других reference_id
.) Запись начинается там, где заканчивалась предыдущая. Теперь я хочу найти все записи, между которыми есть пробел, где from
позже, чем before
предыдущего. Например (изменение в строке 2
, столбец from
):
id | from | before | reference_id
-------------------------------------------
1 | 2019-03-01 | 2019-03-05 | 5
5 | 2019-03-06 | 2019-03-09 | 5
8 | 2019-03-09 | NULL | 5
Строка 2 from
на один день позже, чем строка 1 before
, это разрыв. Проблема: для строк 3 и 1 то же самое верно, но они не должны рассматриваться как результат, потому что между ними есть другая строка.
Я придумал вот что:
SELECT *
FROM mytable mt1
INNER JOIN mytable mt2 ON mt1.reference_id = mt2.reference_id AND mt1.id != mt2.id
WHERE mt1.before IS NOT NULL
AND mt1.from < mt2.from
AND DATE_ADD(mt1.before, INTERVAL 1 DAY) = mt2.from
AND NOT EXISTS(SELECT * FROM mytable mt3 WHERE mt3.id BETWEEN mt1.id AND mt2.id)
Однако, это (EXISTS
) невероятно медленно. Есть ли лучший способ сделать это?
[править] Запрос только что завершился, и я не получил никаких результатов, хотя я определенно ожидаю некоторых. Так что это не только медленно, но и некорректно. [/ Edit]
План выполнения:
1,PRIMARY,mt1,ALL,"mytable_48d78c2b,mytable_261384ee,mytable_849034da",,,,3313021,Using where
1,PRIMARY,mt2,ref,"mytable_48d78c2b,mytable_849034da",mytable_849034da,4,db.mt1.reference_id,1,Using index condition; Using where
2,DEPENDENT SUBQUERY,mt3,index,PRIMARY,mytable_48d78c2b,3,,3313021,Using where; Using index