SQL - 依赖于 2 个表的查询?

Posted

技术标签:

【中文标题】SQL - 依赖于 2 个表的查询?【英文标题】:SQL - query that dependent on 2 tables? 【发布时间】:2013-12-11 21:07:50 【问题描述】:

我有一个包含 2 个表的数据库:

    企业。 优惠券

Businesses 中的每一行都有以下字段:

id, details, image, name, location_x, location_y,

其中location_xlocation_y 是谷歌地图的latituelongitue 坐标。

Coupons表中,每一行都有以下字段:

id, business_id, image, details, goneDate, goneHour

id是优惠券id

business_id 是这张优惠券所属的businessid

我的问题:

通过查询Coupons,如何从给定坐标中获取其所有者业务位置半径小于10km的所有优惠券?

或者换句话说,就是这样的人:

如何获取每个优惠券商家id,然后到商家表中,查看商家id位置的半径是否小于给定位置10公里?

我认为它与inner join有关,不确定。

我正在使用 Java 的 hibernate 框架工作。

请帮助我,在此先感谢!

【问题讨论】:

只要知道根据地图坐标计算距离的公式,剩下的就是小菜一碟了INNER JOIN 您使用的是什么数据库引擎?例如,SQL Server 支持内置空间坐标。 @PM77-1 如何使用INNER JOIN? Sql 服务器?没有 francis OP 表示他正在使用 nhibernate,他需要链接或 hql。顺便说一句,在 where 子句中放置 WHERE (X 在坐标 - 10km 和坐标 + 10km 之间) AND(samething to Y) 在这种情况下,这可能会有所帮助:dev.mysql.com/doc/refman/5.0/en/spatial-extensions.html 【参考方案1】:

这可以通过数学来完成! 首先我们知道给定一个Point P(x, y),P 位于Circle 内,Center C(a,b)Radius r

如果它满足方程(x-a)^2 + (y - b)^2 <= r^2

因此,在您的情况下,中心将是提供的初始坐标。

为了获取位于给定半径内的企业的所有优惠券,这个查询应该可以解决问题。

SELECT 
    bus.id, coup.id 
FROM 
    Businesses AS bus INNER JOIN 
    Coupons AS coup 
WHERE
    bus.id = coup.business_id AND
    (acos(sin(radians(business.location_y)) * sin(radians(a)) + cos(radians(business.location_y)) * cos(radians(a)) * cos(radians(business.location_x) - radians(b)) * 6371) <= 10;

在上述查询a is input_yb is input_xr is the radius = 10。查询假设地球半径为 6371 KM。

已编辑:在与@acfrancis 讨论后,我使用更适合计算球体上点之间距离的方程重写了查询。这应该适用于您的用例(即使地球不是完美的球体)。使用的所有函数都是 postgres 特定的。详情可以看这里http://en.wikipedia.org/wiki/Great-circle_distance。

【讨论】:

不要将纬度/经度与笛卡尔平面上的 X/Y 坐标混淆。例如,同一纬度且相隔 1 度经度的两点之间的距离取决于纬度。靠近两极,距离很小,但在赤道上,距离很大。正确的计算并非易事。这就是为什么我建议尽可能使用内置功能。 是的,你是绝对正确的。但是在用例中,在 10 公里距离处描述的 OP 使用这个方程的误差范围可以忽略不计。如果用例需要高精度,那么提出查询将有点困难:) 这不是精度问题。您的公式返回应用于这两组点的相同距离,以(纬度,经度)度为单位:[(0, 0); (0, 0.1)] 和 [(180, 0); (180, 0.1)]。第一组在赤道上,实际距离约11km。第二秒在北极,距离为零。 首先没有纬度180度这样的东西。有效范围是 -90 到 +90。其次,即使您的意思是 (long, lat)=(180,0),那仍然不是北极。北极是 (90,0)。无论如何,这种解决方案显然并不完美,但如果不采取极端情况,它就可以完成这项工作。 至于其余部分,location_x、location_y、a 和 b(最有可能)是十进制度。将它们(where 子句表达式的左侧)与 km(右侧)进行比较是没有意义的。【参考方案2】:

我认为这不能仅在 SQL 中完成,因为您需要进行一些计算来确定企业与给定位置之间的距离。

可以查询商家,计算所有距离,扔掉超过 10 公里的距离,然后查询优惠券。

SELECT * FROM coupons WHERE business_id IN array of your <10km business ids

如果您只是想获得与企业内部加入匹配的优惠券的结果,那么您会工作

SELECT * FROM coupons INNER JOIN businesses ON coupons.business_id = businesses.id

【讨论】:

【参考方案3】:

您必须使用公式计算距离。您的问题在这里有答案:Finding a geography point within a range of another - SQL Server

【讨论】:

以上是关于SQL - 依赖于 2 个表的查询?的主要内容,如果未能解决你的问题,请参考以下文章

如何查询 BigQuery 视图和表的依赖关系?

如何使用 3 个表在 SQL 查询中获得完整结果,其中 1 个表保持 2 个表的关系?

跨 2 个表的 Mysql SQL 查询 - 不知道如何正确执行

SQL Server:根据来自其他 2 个表的子查询从表中选择

带有 2 个表的 SQL Server GROUP BY

优化联合 sql 查询