SQL查询的说明

时间:2013-12-04 15:24:24

标签: mysql sql stored-procedures

我对此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;
  

问题:对“拥有”关键字以及距离发挥作用的地方感到困惑。它是否试图从桌子上抓住距离,因为这显然是在飞行中计算的。

2 个答案:

答案 0 :(得分:3)

第一部分

*选择所有列。您可以使用点表示法指定特定表的所有列,就像用于指定表的单个列一样。例如:

SELECT t1.* FROM t1 NATURAL JOIN t2

在JOIN中仅使用来自SELECT的{​​{1}}列,即使t1。{/ p>

下一部分

这只是对某些列进行数学计算,并将结果别名为t2(而非“目标”)。您可以在结果集中将结果引用为distancedistance关键字设置列别名,但它是可选的。

第三部分

ASdestination是别名。他们不使用可选的origin关键字。写道也是一样:

AS

FROM users AS destination, users AS origin 表在查询期间被重命名,因此它可以被别名引用,但也可以避免查询中两个相同的表名冲突,这将无效。

最后一部分

users是上面数学计算的别名。 distanceHAVING类似,但必须用于汇总(例如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; - 为了避免计算实际的地理距离?