2016-06-07 49 views
0

我有一个PostgreSQL数据库9.5三个表:INNER JOIN与另外两个人一个桌子,仿佛它们是外连接

big_table: 
- geom_location 
a: 
- geom_location 
- name 
b: 
- geom_location 
- name 

的geom_location领域是已索引PostGIS的领域。 a和b表格大约为200K行,而big_table大约为20M行。
我需要创建产生以下结果的select语句:

  • a_name - 如果在表内的geom_location 2公里一个BIG_TABLE项,这将是其关联的名称。否则,它将为空。
  • b_name - 如果表b中geom_location的2Km内有一个big_table条目,这将是它的关联名称。否则,它将为空。
  • geom_location - 表a,b或两者中的条目2Km内的geom_location。
  • 我不想找回其中a_name和b_name都为空的任何行。

以下是接近我想要的东西,但它需要所有三个geom_locations是2公里范围内:

SELECT t.geom_location, a.name as a_name, b.name as b_name 
FROM big_table t 
INNER JOIN a ON ST_DWithin(t.geom_location, a.geom_location, 2000) 
INNER JOIN b ON ST_DWithin(t.geom_location, b.geom_location, 2000) 

这也是八九不离十,但它并没有合并行的路上我想:

SELECT t.geom_location, a.name as a_name, null as b_name 
FROM big_table t 
INNER JOIN a ON ST_DWithin(t.geom_location, a.geom_location, 2000) 
UNION 
SELECT t.geom_location, null as a_name, b.name as b_name 
FROM big_table t 
INNER JOIN b ON ST_DWithin(t.geom_location, b.geom_location, 2000) 

好像应该有应该有一些语法,做一个“大多是”内部连接 ​​- 也就是说,在两个表格作出关于内内加盟的第一个表,而是彼此之间的完全结合。

回答

0

这是做你想做的吗?

SELECT t.geom_location, a.name as a_name, b.name as b_name 
FROM big_table t LEFT JOIN 
    a 
    ON ST_DWithin(t.geom_location, a.geom_location, 2000) LEFT JOIN 
    b 
    ON ST_DWithin(t.geom_location, b.geom_location, 2000) AND a.name IS NULL 
WHERE a.name IS NOT NULL OR b.name IS NOT NULL; 

或者,你可以结合ab在一起:

SELECT t.geom_location, ab.name, ab.which 
FROM big_table t JOIN 
    ((SELECT a.name a.geom_location, 'a' as which 
     FROM a 
    ) UNION ALL 
     (SELECT a.name b.geom_location, 'b' as which 
     FROM b 
    ) 
    ) ab 
    ON ST_DWithin(t.geom_location, ab.geom_location, 2000) ; 

编辑:

其实我在想,上述方案可能有一些性能困难。它适用于简单的数据类型,但复杂的类型总是有点麻烦。但是,你仍然可以做你想做的事。这是你的union方法的变化:

与助教( SELECT t.geom_location,a.name为a_name,null作为b_name FROM BIG_TABLE牛逼INNER JOIN 一个 ON ST_DWithin

(t.geom_location,一。 geom_location,2000 ) SELECT TA * 自TA UNION ALL SELECT t.geom_location,null作为a_name,b.name如b_name FROM BIG_TABLE吨INNER JOIN b ON ST_DWithin(t.geom_location,b.geom_location ,2000) 不存在(SELECT 1 FROM ta WHERE t.geom_location = ta.geom_location );

我很确定=应该在位置列上工作。

+0

我认为这样做,但不幸的是在这样的左外连接中使用ST_DWithin不会使用它的索引。 postgres对该查询的解释返回的成本超过2万亿! – bsellersful

相关问题