Я не думаю, что будет действительно быстрое решение для этого, так как оно требует сравнения каждой строки в таблице с каждой другой строкой в таблице (или, по крайней мере, с каждой другой строкой в указанном диапазоне).
Предполагая, что столбец первичного ключа вашей таблицы называется id
, вы можете использовать функцию диапазона Postgres для проверки перекрывающихся строк:
with check_period (check_range) as (
values ( tstzrange(timestamptz '2018-10-01 00:00:00', timestamptz '2018-10-14 20:15:00') )
)
select id,
start_Time,
end_time,
exists (select *
from the_table t2
cross join check_perioud
where t2.id <> t1.id
and tstzrange(t1.start_time, t1.end_time) && tstzrange(t2.start_time, t2.start_time)
and tstzrange(t2.start_time, t2.start_time) <@ check_range
) has_overlapping_rows
from the_table t1
cross join check_period
where tstzrange(t1.start_time, t1.end_time) <@ check_range;
CTE check_period
только там, так что значения для периода времени, который вы хотите проанализировать, не повторяются.Если вам не нужно повторять их, вы можете удалить их:
select id,
start_Time,
end_time,
exists (select *
from the_table t2
where t2.id <> t1.id
and tstzrange(t1.start_time, t1.end_time) && tstzrange(t2.start_time, t2.start_time)
and tstzrange(t2.start_time, t2.start_time) <@ tstzrange(timestamptz '2018-10-01 00:00:00', timestamptz '2018-10-14 20:15:00')
) has_overlapping_rows
from the_table t1
where tstzrange(t1.start_time, t1.end_time) <@ tstzrange(timestamptz '2018-10-01 00:00:00', timestamptz '2018-10-14 20:15:00');
Чтобы сделать это быстрым, вам нужно создать индекс в диапазоне временных отметок:
create index on the_table( (tstzrange(start_time, end_time), id );
Вы можете расширить приведенный выше запрос, чтобы он возвращал количество перекрывающихся строк, а не флаг истины / ложи:
select id,
start_Time,
end_time,
(select count(*)
from the_table t2
where t2.id <> t1.id
and tstzrange(t1.start_time, t1.end_time) && tstzrange(t2.start_time, t2.start_time)
and tstzrange(t2.start_time, t2.start_time) <@ tstzrange(timestamptz '2018-10-01 00:00:00', timestamptz '2018-10-14 20:15:00')
) has_overlapping_rows
from the_table t1
where tstzrange(t1.start_time, t1.end_time) <@ tstzrange(timestamptz '2018-10-01 00:00:00', timestamptz '2018-10-14 20:15:00');
Однако для строк, имеющих много перекрывающихся строк, это будет медленнее, поскольку силы count(*)
база данных для проверки всех перекрывающихся строк.Решение exists()
может остановиться на первой найденной строке.