【问题标题】:Best way to join on a range?加入范围的最佳方式?
【发布时间】:2013-06-26 20:04:06
【问题描述】:

我认为这可能是一个常见问题,可能无法为每个工具提供答案。现在我们正在尝试使用亚马逊 Redshift。我们现在唯一的问题是我们正在尝试查找 IP 地址的邮政编码。我们拥有的将 IP 连接到城市的表是 IP 转换为整数的范围。

例子:

Start IP | End IP  | City

| 123123 | 123129 | Rancho Cucamonga|

我已经在 intip >= startip 和 intip

有谁知道这样做的好方法吗?

【问题讨论】:

    标签: sql postgresql amazon-redshift range-types


    【解决方案1】:

    从 PostgreSQL 9.2 开始,您可以使用新的 range typesint4rangeint8range 之一。

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

    那么您的查询可能只是:

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

    &lt;@.."element is contained by"

    要使大表的速度更快,请使用 GiST 索引:

    CREATE INDEX city_ip_range_idx ON city USING gist (ip_range);
    

    但我怀疑 Amazon Redshift 是否是最新的。我们最近有其他人遇到问题:
    Using sql function generate_series() in redshift

    【讨论】:

    • Redshift 实际上不是 PostgreSQL,它是 ParAccel,是 Pg 8.1 的一个分支,具有各种列存储功能等。
    【解决方案2】:

    尝试使用between,列出目标值的表:

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

    并确保table2.ip 上有索引。

    它应该表现得很好。

    【讨论】:

      【解决方案3】:

      假设范围包含在 TableA 中,并且 ID 在 TableB 中,则以下查询应该使用 SQL

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-11-06
        • 2015-01-18
        • 1970-01-01
        • 2020-10-25
        • 2020-08-13
        • 2016-12-13
        相关资源
        最近更新 更多