我对此SQL查询有一些问题。这实际上来自处理空间计算的程序。该过程查找特定半径内的位置。真的,我很难理解发生了什么。如果有人可以帮助解释一些事情,我只需要为我的目的重写它。我将永远感激任何想要帮助的人。非常感谢提前!
链接到来源:http://www.scribd.com/doc/2569355/Geo-Distance-Search-with-MySQL
完整程序 - 我只需要对实际SELECT语句提供一些解释帮助 - 这只是为了澄清所以无论谁阅读都可以获得更好的理解
CREATE PROCEDURE geodist (IN userid int, IN dist int)BEGINdeclare mylon double; declare mylat double;declare lon1 float; declare lon2 float;declare lat1 float; declare lat2 float;
-- get the original lon and lat for the userid
select longitude, latitude into mylon, mylat from users5where id=userid limit 1;
-- calculate lon and lat for the rectangle:
set lon1 = mylon-dist/abs(cos(radians(mylat))*69);set lon2 = mylon+dist/abs(cos(radians(mylat))*69);set lat1 = mylat-(dist/69); set lat2 = mylat+(dist/69);
-- run the query:
SELECT destination.*,3956 * 2 * ASIN(SQRT( POWER(SIN((orig.lat -dest.lat) * pi()/180 / 2), 2) +COS(orig.lat * pi()/180) * COS(dest.lat * pi()/180) *POWER(SIN((orig.lon -dest.lon) * pi()/180 / 2), 2) )) asdistance FROM users destination, users originWHERE origin.id=userid
and destination.longitude between lon1 and lon2 and destination.latitude between lat1 and lat2
having distance < dist ORDER BY Distance limit 10;END $$
完整查询我需要澄清的部分:
SELECT destination.*,3956 * 2 * ASIN(SQRT( POWER(SIN((orig.lat -dest.lat) * pi()/180 / 2), 2) +COS(orig.lat * pi()/180) * COS(dest.lat * pi()/180) *POWER(SIN((orig.lon -dest.lon) * pi()/180 / 2), 2) )) as distance FROM users destination, users origin WHERE origin.id=userid
and locations.longitude between lon1 and lon2 and locations.latitude between lat1 and lat2
having distance < dist ORDER BY Distance;
第一部分:
SELECT destination.*
问题:目的地一词后的期间和*是什么?当然,我们正在选择目的地,但这是连锁吗?就像将目的地前缀加到表格中的每一列一样?
下一部分:
3956 * 2 * ASIN(SQRT( POWER(SIN((orig.lat -dest.lat) * pi()/180 / 2), 2) +COS(orig.lat * pi()/180) * COS(dest.lat * pi()/180) *POWER(SIN((orig.lon -dest.lon) * pi()/180 / 2), 2) )) as distance
问题:这只是执行计算并将其存储为关键字目标吗?关键字“as”将我抛弃。是在数据库中搜索列目的地吗?
第三部分:
FROM users destination, users origin WHERE origin.id=userid
问题:对查询的位置有点困惑。用户目的地?用户来源?这抓住了什么?
最后一部分:
having distance < dist ORDER BY Distance;
问题:对“拥有”关键字以及距离发挥作用的地方感到困惑。它是否试图从桌子上抓住距离,因为这显然是在飞行中计算的。
答案 0 :(得分:3)
*
选择所有列。您可以使用点表示法指定特定表的所有列,就像用于指定表的单个列一样。例如:
SELECT t1.* FROM t1 NATURAL JOIN t2
在JOIN中仅使用来自SELECT
的{{1}}列,即使t1
。{/ p>
这只是对某些列进行数学计算,并将结果别名为t2
(而非“目标”)。您可以在结果集中将结果引用为distance
。 distance
关键字设置列别名,但它是可选的。
AS
和destination
是别名。他们不使用可选的origin
关键字。写道也是一样:
AS
FROM users AS destination, users AS origin
表在查询期间被重命名,因此它可以被别名引用,但也可以避免查询中两个相同的表名冲突,这将无效。
users
是上面数学计算的别名。 distance
与HAVING
类似,但必须用于汇总(例如WHERE
)。我可能是错的,但我不认为这个查询是必要的。
答案 1 :(得分:0)
我觉得我在这里遗漏了一些东西......为什么代码不使用&#39; mylon&#39;和&#39; mylat&#39;在最终查询的数学部分?
所以,这个:
SELECT destination.*,
3956 * 2 * ASIN(SQRT( POWER(SIN((orig.lat -
destination.lat) * pi()/180 / 2), 2) +
COS(orig.lat * pi()/180) * COS(destination.lat * pi()/180) *
POWER(SIN((orig.lon -destination.lon) * pi()/180 / 2), 2) ))
as distance
FROM users AS destination, users AS orig
WHERE origin.id=userid
AND destination.longitude BETWEEN lon1 AND lon2
AND destination.latitude BETWEEN lat1 AND lat2
HAVING distance < dist ORDER BY Distance limit 10;
成为这个:
SELECT destination.*,
3956 * 2 * ASIN(SQRT( POWER(SIN((mylat -
dest.lat) * pi()/180 / 2), 2) +
COS(mylat * pi()/180) * COS(dest.lat * pi()/180) *
POWER(SIN((mylon -dest.lon) * pi()/180 / 2), 2) ))
as distance
FROM users AS destination
WHERE
destination.longitude BETWEEN lon1 AND lon2
AND destination.latitude BETWEEN lat1 AND lat2
HAVING distance < dist ORDER BY Distance limit 10;
编辑:我最好的猜测是&#34; origin.id = userid&#34;应阅读&#34; origin.id = destination.id&#34;。我是否正确认为已完成此连接以过滤掉距离框外的所有用户&#34; - 为了避免计算实际的地理距离?