需要专家帮助解决空间数据查询中的微小变化

时间:2014-06-17 11:49:08

标签: mysql sql geospatial spatial spatial-query

我有以下查询来访问给定lat-lon周围的最近位置。 我跟着 Mr.Ollie的博客Nearest-location finder for MySQL使用半正式公式查找了给定lat-long附近的最近位置。

但由于空间数据查询缺乏太多知识,我未能正确执行,所以寻找专家的建议来解决这个问题。

这是我的查询

  SELECT z.id,
       p.distance_unit
                * DEGREES(ACOS(COS(RADIANS(p.latpoint))
                * COS(RADIANS(z.(x(property))))
                * COS(RADIANS(p.longpoint) - RADIANS(z.(y(property))))
                + SIN(RADIANS(p.latpoint))
                * SIN(RADIANS(z.(x(property)))))) AS distance_in_km
 FROM mytable AS z
 JOIN (   /* these are the query parameters */
       SELECT  12.00  AS latpoint,  77.00 AS longpoint,
               20.0 AS radius,      111.045 AS distance_unit
   ) AS p
 WHERE z.(x(property))
    BETWEEN p.latpoint  - (p.radius / p.distance_unit)
        AND p.latpoint  + (p.radius / p.distance_unit)
   AND z.(y(property)
    BETWEEN p.longpoint - (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
        AND p.longpoint + (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
 ORDER BY distance_in_km
 LIMIT 15;

当我运行此查询时,我收到错误

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(x(property))))                 * COS(RADIANS(p.longpoint) - RADIANS(z.(y(geo' at line 1

我也试过z.(GeomFromText(x.property)))

这是我的表 desc

+-----------+----------------+
| Field     |    Type        |
+-----------+----------------+
|  id       |        Int(10) |
| property  |       geometry |
+-----------+----------------+

select x(property) from mytable; //gives me lat 
select y(property) from mytable; //gives me lan

我哪里错了? 这是实现这一目标的方法吗?

请建议。

2 个答案:

答案 0 :(得分:1)

在我看来,您假设在查询中选择z.id后,您可以直接访问x(property)y(property)

(除此之外 - 这些名字真的有括号吗?)

所以对我而言,你应该更换像

这样的东西
* COS(RADIANS(z.(x(property))))

类似

* COS(RADIANS( select x(property) from mytable where id = z.id ))

然而,在进一步思考它时,我认为您的mytable没有所需的结构。通过查看链接,我相信您的mytable应该具有更像的结构:

+-----------+----------------+
| Field     |    Type        |
+-----------+----------------+
|  id       |        Int(10) |
| latitude  |        Float   |
| longitude |        Float   |
+-----------+----------------+

这样你就可以做一些像

这样的事情
* COS(RADIANS(z.latitude))

注意

以上是基于我不理解MySQL支持空间数据类型(我不知道如何使用)

<强>更新

我只是用谷歌搜索了解空间类型并发现了这个:

How do you use MySQL spatial queries to find all records in X radius? [closed]

这表明您无法执行您想要在mysql中使用空间数据类型的操作。因此,您将回到使用在mutable

中存储数据的非最佳方式

然而,在重新阅读该链接时,对答案的评论表明您现在可以使用空间数据类型。 (我告诉过你我在这里没有线索)这意味着用ST_Distance(g1,g2)之类的东西替换查询代码,这实际上意味着完全重写了这个例子。

换句话说

  

您给出的示例假设空间数据类型和测试   MySQL中不存在几何。但是现在他们确实存在了,他们   使这组示例代码无关紧要,并且您正在使用   如果你尝试结合两种形式的分析,就会受到伤害。

更新2

您可以遵循三种途径:

  1. 否认MySQL中存在空间数据类型并使用具有latlong的显式列的表,并使用最初在该博客上编写的示例代码。

  2. 接受MySQL空间数据类型(疣和所有)并查看类似于答案https://stackoverflow.com/a/21231960/31326的内容,这些内容似乎可以直接用空间数据类型执行,但正如答案中所述有一些警告。

  3. 使用空间类型来保存您的数据,并使用pre-query提取latlong,然后再将其传递到原始示例代码中。

    < / LI>

答案 1 :(得分:0)

最后我跟着this link并以此结束。 查询尚未优化但工作得很好。

这是我的查询

select id, ( 3959 * acos( cos( radians(12.91841) ) * cos( radians( y(property) ) ) * cos( radians( x(property)) - radians(77.58631) ) + sin( radians(12.91841) ) * sin( radians(y(property) ) ) ) ) AS distance from mytable having distance < 10 order by distance limit 10;