简体   繁体   English

基于st_dwithin条件的BigQuery Left Join就像一个内部联接

[英]BigQuery Left Join based on st_dwithin condition acting like an Inner Join

I need help with the following... 我需要以下帮助...

I've created a query that should join the records from another table based on a certain distance between two coordinates. 我创建了一个查询,该查询应基于两个坐标之间的一定距离来连接来自另一个表的记录。 I end up with a table that only has records with matching location names (like an inner join). 我最后得到一个表,该表仅包含具有匹配位置名称的记录(例如内部联接)。 I need every record in the table_customer_x and locationname should be a null if the distance between any location for that customer is > 250. 我需要table_customer_x中的每条记录,并且如果该客户的任何位置之间的距离> 250,则locationname应该为null。

The query that I created: 我创建的查询:

 SELECT t.customerid, t.geolatitude, t.geolongitude, tt.locationname
 FROM `table_customer_x` t
 LEFT JOIN  `table_location` tt  
 on ST_DWITHIN(ST_GEOGPOINT(t.geoLatitude,t.geoLongitude), ST_GEOGPOINT(tt.latitude, tt.longitude), 250)
 where tt.customer_id= 204
 and t.timestamp > "2016-01-01"
 and tt.latitude <= 90 and tt.latitude >= -90

table_customer_x looks like: table_customer_x看起来像:

timestamp             geoLatitude       geoLongitude    
2018-01-01 00:00:00       52.000             4.000

table_location looks like: table_location看起来像:

latitude       longitude       name      customer_id
 52.010          4.010      hospital x     204

[Why] BigQuery Left Join based on st_dwithin condition acting like an Inner Join [为什么]基于st_dwithin条件的BigQuery左联接的行为类似于内部联接

In BigQuery, Spatial JOINs are implemented for INNER JOIN and CROSS JOIN operators with the following standard SQL predicate functions: 在BigQuery中,使用以下标准SQL谓词函数为INNER JOIN和CROSS JOIN运算符实现了空间联接:

ST_DWithin
ST_Intersects
ST_Contains
ST_Within
ST_Covers
ST_CoveredBy
ST_Equals
ST_Touches   

So, you cannot expect LEFT JOIN to work properly in your case - instead - your left JOIN is "converted" into CROSS JOIN with filter in ON clause moved into Where clause 因此,您不能指望LEFT JOIN在您的情况下能正常工作-而是-您的左JOIN被“转换”为CROSS JOIN且将ON子句中的过滤器移到Where子句中
So result you see is as expected 所以你看到的结果是预期的

Summary - you just need to rewrite your query :o) 摘要-您只需要重写查询:o)

You can try something like below to workaround (not tested - just possible direction for you) 您可以尝试以下类似的解决方法(未经测试-只是可能的指示)

#standardSQL
SELECT tt.customer_id, t.geolatitude, t.geolongitude, tt.name
FROM `project.dataset.table_customer_x` t
JOIN  `project.dataset.table_location` tt  
ON ST_DWITHIN(ST_GEOGPOINT(t.geoLatitude,t.geoLongitude), ST_GEOGPOINT(tt.latitude, tt.longitude), 250)
UNION ALL
SELECT tt.customer_id, t.geolatitude, t.geolongitude, tt.name
FROM `project.dataset.table_customer_x` t
JOIN  `project.dataset.table_location` tt  
ON NOT ST_DWITHIN(ST_GEOGPOINT(t.geoLatitude,t.geoLongitude), ST_GEOGPOINT(tt.latitude, tt.longitude), 250)
WHERE tt.customer_id= 204
AND t.timestamp > "2016-01-01"
AND tt.latitude <= 90 AND tt.latitude >= -90

It could have been a BigQuery bug, seems to be fixed now. 可能是BigQuery错误,现在似乎已修复。

Geospatial outer join is not yet implemented, so this query should fail with message LEFT OUTER JOIN cannot be used without a condition that is an equality of fields from both sides of the join. 地理空间外部LEFT OUTER JOIN cannot be used without a condition that is an equality of fields from both sides of the join.尚未实现,因此,如果没有LEFT OUTER JOIN cannot be used without a condition that is an equality of fields from both sides of the join.该查询应失败,并显示消息LEFT OUTER JOIN cannot be used without a condition that is an equality of fields from both sides of the join.

The workaround is to simulate outer join using inner join: do inner join, then union with unmatched rows on the left side. 解决方法是使用内部联接模拟外部联接:执行内部联接,然后与左侧不匹配的行合并。 It requires some unique key on the outer side to work properly, I'm not sure if you have one in table_customer_x. 它需要在外面有一些唯一的键才能正常工作,我不确定table_customer_x中是否有一个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM