2011-10-10 35 views
2

我有下一个查询获取给定距离内的地址和给定的邮政编码。根据经度和纬度数据计算距离。MySQL计算距离(简单解决方案)

在这个例子中我已经取代了用户输入的只是值(LAT = 52.64,长= 6.88烯期望的距离=10公里)

查询:

SELECT *, 
ROUND(SQRT(POW(((69.1/1.61) * ('52.64' - latitude)), 2) + POW(((53/1.61) * ('6.88' - longitude)), 2)), 1) AS distance 
FROM lp_relations_addresses distance 
WHERE distance < 10 
ORDER BY `distance` DESC 

给出未知柱距离作为错误信息。 当我离开时,我得到了桌子上的每个记录,包括他们的计算距离。在这种情况下,我必须获取整个表格。

我如何获得只需要的记录?

在此先感谢您的任何意见!

回答

4

你不能从SQL语句的另一部分引用的别名选择子句。你需要把你的WHERE子句中的整个表达式:

WHERE 
    ROUND(SQRT(POW(((69.1/1.61) * ('52.64' - latitude)), 2) 
     + POW(((53/1.61) * ('6.88' - longitude)), 2)), 1) < 10 

一个清洁的解决方案是使用一个子查询产生的计算数据:

SELECT *, distance 
    FROM (
     SELECT *, 
      ROUND(SQRT(POW(((69.1/1.61) * ('52.64' - latitude)), 2) 
       + POW(((53/1.61) * ('6.88' - longitude)), 2)), 1) AS distance 
      FROM lp_relations_addresses 
     ) d 
    WHERE d.distance < 10 
ORDER BY d.distance DESC 

演示:http://www.sqlize.com/q96p2mCwnJ

+0

再次感谢!现在是我睡觉的时候了:)这个问题太容易解决..... – Terradon

+0

明天我会尝试一下你的清洁解决方案,并将它们与Explain进行比较,很多再次感谢,你的贡献为我节省了很多时间! – Terradon

+2

+1为sqlize站点:) –

1

您将计算混淆为“距离”,但您也将“lp_relations_addresses”表替换为“距离”。试着给他们这样一个不同的名称:

SELECT *, 
ROUND(SQRT(POW(((69.1/1.61) * ('52.64' - latitude)), 2) + POW(((53/1.61) * ('6.88' - longitude)), 2)), 1) AS distance 
FROM lp_relations_addresses addr 
WHERE distance < 10 
ORDER BY `distance` DESC 
+0

我想你的代码了,但是在clausule给出了一个未知的列距离误差距离。 – Terradon

+0

在桌子上别名发生冲突,但作为mellamokb笔记,您不能在* where *中使用别名,但是您可以在*有*的情况下使用Ilmari笔记... – StuartLC

2

由于mellamokb notes,您不能在WHERE子句中引用列别名。 You can, however, do it in a HAVING clause

SELECT *, 
    ROUND(SQRT(POW(((69.1/1.61) * ('52.64' - latitude)), 2) + 
     POW(((53/1.61) * ('6.88' - longitude)), 2)), 1) AS distance 
FROM lp_relations_addresses 
HAVING distance < 10 
ORDER BY distance DESC 

Ps。如果你有很多地址,你可能要考虑优化查询,尽早排除一些查询。例如,用合适的指标,以下版本可能相当快:

SELECT *, 
    ROUND(SQRT(POW(((69.1/1.61) * ('52.64' - latitude)), 2) + 
     POW(((53/1.61) * ('6.88' - longitude)), 2)), 1) AS distance 
FROM lp_relations_addresses 
WHERE latitude > '52.64' - 10/(69.1/1.61) 
    AND latitude < '52.64' + 10/(69.1/1.61) 
    AND longitude > '6.88' - 10/(53/1.61) 
    AND longitude < '6.88' + 10/(53/1.61) 
HAVING distance < 10 
ORDER BY distance DESC 
+0

+1你需要在'HAVING'子句后加上'ORDER BY'子句*,那么它的工作原理非常好:http://www.sqlize.com/7e8TpPqiuj – mellamokb

+0

@mellamokb:谢谢,修正。 –

+0

谢谢大家的贡献!救了我一些头痛 – Terradon