Mysql 从类别和半径内查找坐标的复杂查询

Mysql 从类别和半径内查找坐标的复杂查询,mysql,coordinates,Mysql,Coordinates,我很难提出一个涉及项目、类别和用户的相当复杂的查询。所有这些都必须放在一起,以便在半径范围内插入新项目时通知已选择要监视的给定类别的用户 我已经有了这个查询,用于计算坐标和其他项目之间的距离 SELECT i.id, ( 3959 * acos( cos( radians(-22.915037) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(-43.207169) ) + sin( radians(-22.915037) )

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

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

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语句中。让我再解释一下。这有点棘手

坐标(纬度、长度)在用户表中。用户拥有项目,并且项目属于给定类别。有一个表(我们称之为监视器),用户可以选择一个类别和半径(1、5、10、50km等)

每次插入一个新项目时,我都将其放在一个单独的表中(我们称之为NewItems),这样我就可以单独处理它

我想要的是,每次执行某个进程时,获取NewItems中的所有项目,并检查它们是否与Monitor中监视的类别匹配,是否在配置的radius范围内,以便我可以通知在该类别和radius中拥有监控器的每个用户

最后,我需要的只是一个带有ItemID和UserID的resultset(或表),这样我就可以给每个用户发送电子邮件,告诉他们在他们监视的类别和半径中插入了一个新项目

关于我的表的更多细节(足以理解如何构建查询)

用户:id、lat、lng

项目:id、用户id、类别id

类别:id、名称

监视器:类别id、用户id、半径


NewItems:item\u id,flag\u notified

这样的东西怎么样

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
选择不同的u.id,n.id
来自用户u
加入监视器m
on u.user\u id=m.owning\u user\u id
加入新项目
在n.category\u id=m.category\u id上
和(3959*acos(弧度(u.lat))*cos(弧度(n.lat))*cos(弧度(n.lng)-弧度(u.lng))+sin(弧度(u.lat))*sin(弧度(n.lat)))*1.6
这假设位置属于用户,并且监控器是类别和半径的组合


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

感谢您的努力,但是NewItems表格没有坐标(它只有Item_id),您有
n.lat
n.long
。这是我面临的主要问题之一。也许是另一种计算半径的方法?我添加了表格细节,以帮助理解问题的“复杂性”。)您如何知道
NewItems
在哪里?如果你不知道,这不仅仅是棘手的:这是不可能的。如果您只知道其中一个位置,则无法测试两个位置之间的距离。NewItems是项目,它们属于用户。我最终实现了查询,我只需要加入用户两次(一次用于条目所有者,另一次用于监视用户)。