棘手的查询,以查找类别和半径内的坐标

时间:2014-04-14 20:27:30

标签: mysql coordinates

我无法提出涉及项目,类别和用户的相当复杂的查询。所有这些必须结合在一起,以便在半径内插入新项目时通知已选择要监视的给定类别的用户。

我已经有了这个查询,来计算坐标和其他项目之间的距离。

SELECT i.id, ( 3959 * acos( cos( radians(-22.915037) ) * cos( radians( lat ) ) *
cos( radians( lng ) - radians(-43.207169) ) + sin( radians(-22.915037) )  *sin(radians(lat)) ) )*1.6 AS distance
FROM user u, item i
WHERE u.id = i.user_id
)

但是我在一个SQL语句中无法全部使用它。让我再解释一下。这有点棘手。

坐标(lat,long)位于Users表中。用户具有项目,而项目属于给定类别。有一个表(让我们称之为监视器)用户选择一个类别和一个半径(1,5,10,50km等)。

每次插入新项目时,我都会把它放在一个单独的表上(我们称之为NewItems),所以我可以单独处理它。

我想要的是,每次执行某个进程时,获取NewItems中的所有项目,并检查它们是否与Monitor中监视的类别匹配,并且落在配置的半径内,这样我就可以通知每个拥有的用户该类别和半径中的监视器。

最后,我需要的只是具有ItemID和UserID的结果集(或表),因此我可以通过电子邮件向每个用户发送电子邮件,告诉他们在他们监控的类别和半径中插入了新项目。

我的表格上有更多细节(足以理解应该如何构建查询)。

Users: id, lat, lng

Item: id, user_id, category_id

Category: id, name

Monitor: category_id, user_id, radius

NewItems: item_id, flag_notified

1 个答案:

答案 0 :(得分:0)

这样的事情怎么样?

SELECT DISTINCT u.id, n.id
FROM Users u
JOIN Monitor m
  on u.user_id = m.owning_user_id
JOIN NewItems n
  on n.category_id = m.category_id
 and ( 3959 * acos( cos( radians(u.lat) ) * cos( radians( n.lat ) ) * cos( radians( n.lng ) - radians(u.lng) ) + sin( radians(u.lat) )  *sin(radians(n.lat)) ) )*1.6 < m.radius_in_km

这假定该位置属于用户,并且监视器是类别和半径的组合。

如果你需要性能更好的东西,空间索引可能会消除一些表格扫描。