Best way to join on a range?

孤街醉人 提交于 2019-12-11 02:26:45

问题


I think this may be a common problem that may not have an answer for every tool. Right now we are trying to use amazons Redshift. The only problem we have now is we are trying to do a look up of zip code for an IP address. The table we have that connects IP to city is a range by IP converted to an integer.

Example:

Start IP | End IP  | City

| 123123 | 123129 | Rancho Cucamonga|

I have tried the obvious inner join on intip >= startip and intip < endip.

Does anyone know a good way to do this?


回答1:


Beginning with PostgreSQL 9.2 you could use one of the new range types,int4range or int8range.

CREATE TABLE city (
  city_id serial PRIMARY KEY 
 ,ip_range int4range
 ,city text
 ,zip  text
);

Then your query could simply be:

SELECT c.zip
FROM   city_ip 
WHERE  $intip <@ i.ip_range;

<@ .. "element is contained by"

To make this fast for a big table use a GiST index:

CREATE INDEX city_ip_range_idx ON city USING gist (ip_range);

But I doubt Amazon Redshift is up to date. We had other people with problems recently:
Using sql function generate_series() in redshift




回答2:


Try using between, listing the table with the target value second:

select *
from table1 t1
join table2 t2
  on t2.ip between t1.startip and t1.endip

And make sure there's an index on table2.ip.

It should perform pretty well.




回答3:


Assuming the range is contained within TableA, and the ID is in TableB, the following query should work with SQL

SELECT TableA.*, TableB.*
FROM TableA JOIN TableB 
ON TableA.StartIP <= TableB.ID AND TableB.ID <= TableA.EndIP


来源:https://stackoverflow.com/questions/17375027/best-way-to-join-on-a-range

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!