簡體   English   中英

INNER JOIN一張桌子和另外兩張桌子一樣,好像它們是外部聯接

[英]INNER JOIN one table with two others as though they were outer joins

我在postgreSQL 9.5數據庫中有三個表:

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

geom_location字段是已建立索引的postGIS字段。 a和b表的順序為200K行,而big_table的順序為20M行。
我需要創建一個選擇語句,產生以下結果:

  • a_name-如果表a中geom_location的2Km之內有一個big_table條目,則這將是它的關聯名稱。 否則,它將為null。
  • b_name-如果表b中geom_location的2Km之內有一個big_table條目,則這將是它的關聯名稱。 否則,它將為null。
  • geom_location-表a,b或兩者中的表項的2Km以內的geom_location。
  • 我不想取回其中a_name和b_name均為null的任何行。

以下內容接近我想要的內容,但它要求所有三個geom_locations都在2Km之內:

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)

似乎應該有某種語法可以執行“大部分”內部連接-即,兩個表相對於第一個表將內部作為內部連接,而相對於彼此為完全連接。

這是您想要的嗎?

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方法的一種變體:

WITH ta as(SELECT t.geom_location,a.name為a_name,null為b_name FROM big_table t INNER JOIN a ON ST_DWithin(t.geom_location,a.geom_location,2000)SELECT ta。* FROM ta UNION ALL SELECT t.geom_location, null作為a_name,b.name作為b_name FROM big_table t INNER JOIN b ON ST_DWithin(t.geom_location,b.geom_location,2000)在不存在的地方(從ta WHERE t.geom_location = ta.geom_location中選擇1);

我很確定=應該可以在“位置”列上使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM