#postgresql
#postgresql
Вопрос:
У меня есть два поля с типом range.
Эти два where
выражения дадут одинаковые результаты?
where range1 amp;amp; range2
where not isempty( range1 * range2 )
Ответ №1:
Они действительно будут.
Оба оператора перекрытия ( amp;amp;
) и пересечения ( *
) вычисляются правильно, включая случаи, когда два диапазона имеют общую границу и их пересечение:
- содержит только 1 элемент (= привязка включена в оба)
- не содержит элементов (= граница не включена по крайней мере в 1 из 2 диапазонов)
Следующий запрос проверяет практически все случаи (= пересечения с более чем 1 точкой, ровно 1 точка, 0 точек, но «близко», «по-настоящему» 0 точек и все комбинации включений нижней / верхней границ):
WITH r(range) AS (
VALUES (numrange(0,1,'[]')), (numrange(1,2,'[]')), (numrange(0,2,'[]')), (numrange(5,6, '[]')),
(numrange(0,1,'[)')), (numrange(1,2,'[)')), (numrange(0,2,'[)')), (numrange(5,6, '[)')),
(numrange(0,1,'(]')), (numrange(1,2,'(]')), (numrange(0,2,'(]')), (numrange(5,6, '(]')),
(numrange(0,1,'()')), (numrange(1,2,'()')), (numrange(0,2,'()')), (numrange(5,6, '()'))
)
SELECT * FROM (
SELECT r1.range, r2.range, r1.range amp;amp; r2.range AS UsingOverlap, NOT isempty(r1.range * r2.range) AS UsingIntersect
FROM r r1, r r2
) T
Не стесняйтесь добавлять WHERE UsingOverlap <> UsingIntersect
.