Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
两个值之间的PostgreSQL连接_Postgresql_Between_Cross Join - Fatal编程技术网

两个值之间的PostgreSQL连接

两个值之间的PostgreSQL连接,postgresql,between,cross-join,Postgresql,Between,Cross Join,我有下面的表格,并试图查找数十万个城市的县代码 create table counties ( zip_code_from char(5) not null, zip_code_thru char(5) not null, county_code char(3) not null ); create table cities ( city text not null, zip_code char(5) not null ); 我的第一种方法是在

我有下面的表格,并试图查找数十万个城市的县代码

create table counties (
  zip_code_from  char(5) not null,
  zip_code_thru  char(5) not null,
  county_code    char(3) not null
);

create table cities (
  city      text    not null,
  zip_code  char(5) not null
);
我的第一种方法是在连接中使用“中间人”:

select
  ci.city, ci.zip_code, co.county_code
from
  cities ci
  join counties co on
    co.zip_code between ci.zip_code_from and ci.zip_code_thru
我知道在甲骨文界,这是不受欢迎的,事实上,表现似乎很糟糕。处理大约16000个城市需要8分钟。邮政编码表有大约80000条记录。我猜这个语法是一个美化的交叉连接

from和thru代码都是索引的,我可以控制结构,因此如果有帮助,我可以更改表

我唯一的另一个想法是继续,将表格扩展到所有可能的值——类似于以下内容:

select
  generate_series (
    cast (zip_code_from as int),
    cast (zip_code_thru as int)
  ) as zip_code,
  *
from counties
这会将数据扩展到超过200000条记录,这并不是什么大问题,但我不确定这是否是我唯一的途径来进行不可怕的查询

我猜想,即使是在运行中这样做并且没有索引,也比我的联接中的
之间的
更好,但是我希望有一种替代方法,无论是在SQL方面还是在表本身的结构方面


我曾在其他DBMS平台上看到过这个问题,但我已经能够用PostgreSQL创造出在其他数据库中不可能(或不实用)的小奇迹,所以我希望我错过了一些东西。

几个月后,这个问题再次出现,我决定测试我的一些理论

原始查询:

select
  ci.city, ci.zip_code, co.fips_code
from
  cities ci
  join counties co on
    ci.zip_code between co.from_zip_code and co.thru_zip_code
实际上实现了笛卡尔函数。查询返回34000行,耗时597秒

如果我“预分解”邮政编码范围为离散记录:

with exploded_zip as (
  select
    generate_series (
      cast (from_zip_code as int),
      cast (thru_zip_code as int)
    )::text as zip_code,
    *
  from counties
)
select
  ci.city, ci.zip_code, co.fips_code
from
  cities ci
  join exploded_zip co on
    ci.zip_code = co.zip_code
查询返回完全相同的行,但在2.8秒内完成


因此,似乎底线是在联接(或任何不等式)中使用
介于
之间是一个非常糟糕的主意。

您是否有
城市(邮政编码)和
县(邮政编码从,邮政编码到)
)的索引?作为了解邮政编码的人,我想说您对县的“从到”方法是有缺陷的。没有可以指定给县的邮政编码范围。一些邮政编码实际上跨越多个县。此外,一些城市有几十个邮政编码。这是假设您使用的是美国邮政编码和美国县。@a_horse_和_no_name在邮政编码_from、邮政编码_thru(一个单独的索引,而不是两个单独的索引)上有一个索引,在cities.Zip_代码上没有索引。查询正在扫描整个cities表,所以我认为这不会有帮助。会吗?@CoryatJohn我发现你是对的。在许多情况下,我发现三个县的邮政编码相同(即费尔法克斯,SC 29827),我们必须手动查找。如果你有建议,我会张开双臂欢迎他们。你看过人口普查档案网站了吗?它包含县和“地方”的多边形,加上地方(城市)应该已经具有正确的县FIPS代码。我建议你去寻找那些资源,而不是试图用邮政编码来捏造它。如果你的城市数据库有一个点,你也可以使用县的多边形来做一个简单的多边形点分析,我想你会发现它几乎100%准确。我会用这种方法。