2016-07-06 109 views
0

我有一个SQL查询工作正常,但我觉得必须有一个更有效的写作方式。通过加入两个包含坐标的表A和B,我将比较每个坐标之间的距离(以米为单位)。然后我总结/计数表B中的坐标数是坐标的设定距离内表A和输出结果:我可以使这个SQL查询更有效吗?

select a.name, 
     sum(case when ST_GeodesicLengthWGS84(ST_SetSRID(ST_LineString(a.lat, a.lon, b.lat, b.lon),4326)) < 10.0 then 1 else 0 end) 10mCount, 
     sum(case when ST_GeodesicLengthWGS84(ST_SetSRID(ST_LineString(a.lat, a.lon, b.lat, b.lon),4326)) < 50.0 then 1 else 0 end) 50mCount, 
     sum(case when ST_GeodesicLengthWGS84(ST_SetSRID(ST_LineString(a.lat, a.lon, b.lat, b.lon),4326)) < 1000.0 then 1 else 0 end) 1000mCount 
FROM a JOIN 
    b 
GROUP BY a.name 
ORDER by 1000mCount desc 
LIMIT 10; 

我觉得必须有一个方法来调用ST_GeodesicLengthWGS84(ST_SetSRID(ST_LineString(a.lat, a.lon, b.lat, b.lon), 4326))一次,得到的结果然后每增加10m,50m和1000m计数。

任何想法? 谢谢。

+0

你还没有指定任何连接标准 - 你是否真的想要一个交叉连接(b中的每一行加入的每一行)? – Bohemian

+0

你的权利,我只是意识到我不需要加入。但是,我在做这个总和(case when)时最接近最有效的方式吗? – mike

+0

**我不需要连接**,您已经有一个连接 - 这是一个低效连接(它是一个“交叉连接”)。您需要更好的连接才能使您的查询更高效。 –

回答

1

尝试prequerying,但您的数据仍然需要结果通过每个记录。

select 
     PreQuery.name, 
     sum(case when PreQuery.Geode < 10.0 then 1 else 0 end) 10mCount, 
     sum(case when PreQuery.Geode < 50.0 then 1 else 0 end) 50mCount, 
     sum(case when PreQuery.Geode < 1000.0 then 1 else 0 end) 1000mCount 
    from 
     (select 
       a.name, 
       ST_GeodesicLengthWGS84(ST_SetSRID(ST_LineString(a.lat, a.lon, b.lat, b.lon),4326)) as Geode 
      from 
       a join b 
       (YOU ARE MISSING the JOIN 'ON' clause... how related)) PreQuery 
    GROUP BY 
     PreQuery.name 
    ORDER by 
     1000mCount desc 
    LIMIT 10; 
相关问题