這可以用作蠻力方法(我將列range_start和range_end重命名以避免與保留字「end」衝突):
select *
from t cross join t t2
where t2.source <> t.source
and box(point(t2.range_start,t2.range_start),point(t2.range_end,t2.range_end))
&& box(point(t.range_start,t.range_start),point(t.range_end,t.range_end))
或
select *
from t
where exists (select 1 from t t2
where t2.source <> t.source and box(point(t2.range_start,t2.range_start),point(t2.range_end,t2.range_end))
&& box(point(t.range_start,t.range_start),point(t.range_end,t.range_end)))
然後,您應該能夠使用其主旨在於指數,這可能使其成爲更有效(SEQ掃描+索引掃描):
create index t_range_idx on t using gist (box(point(range_start,range_start),point(range_end,range_end))
此功能可能有助於理解通過清理的SQL:
create function range(not_before int, not_after int) returns box
strict immutable language sql
as $$ select box(point($1,$1),point($2,$2)) $$;
有了這個,你可以這樣寫:
select * from t where range(range_start,range_end) && range(10,20);
並注意運營商的意思是「重疊」。
也許`哪裏a.source <> b.source` – araqnid 2011-01-25 11:14:02
@araqnid - 謝謝。更新了條款 – RichardTheKiwi 2011-01-25 11:15:17