繁体   English   中英

需要帮助了解此sql

[英]Need help understanding this sql

我试图破译此SQL语句。 具体地,什么位置z,位置o,位置是平均值。 在这种情况下,zo和意味着什么? 困惑:(

SELECT o.zip_code
FROM locations z, locations o, locations a

WHERE z.zip_code = #{zip_code}
AND z.zip_code = a.zip_code
AND (3956 * (2 * ASIN(SQRT(
        POWER(SIN(((z.latitude-o.latitude)*0.017453293)/2),2) +
        COS(z.latitude*0.017453293) *
        COS(o.latitude*0.017453293) *
        POWER(SIN(((z.longitude-o.longitude)*0.017453293)/2),2)
    )))) <= #{distance}

这些是表别名...

Aliases are powerful for complex queries that need to 
    use the same table twice but in different ways.

在此查询中,FROM子句为表名指定别名。 别名位置z意味着位置表可以在查询中的其他位置称为z 例如, z.zip_codelocation.zip_code相同。 这样可以节省在此查询中的键入。

参考

它是速记

 locations AS z, locations AS o, locations AS a

换句话说,它们是别名。

不是在整个代码中都写locations ,而是原始作者选择将它们别名为速记,在这种情况下为zo和a。

另外,由于他使用同一个表三遍,因此别名可以使他区分每个表

这是locations表及其自身的笛卡尔乘积两次。 由于查询将同一个表自身连接在一起,因此需要重命名每个部分,以便稍后在查询中唯一标识它们。 zoa是这些名称。

此处查看示例二(http://www.fluffycat.com/SQL/Cartesian-Joins/)以了解发生了什么。 除了在这种情况下,有两种笛卡尔乘积而不是一种。 都在同一张桌子上。

该查询本身可能会很慢,因为它正在执行双笛卡尔乘积,它将创建一个包含n³行和(3m)列的临时表,其中n是位置表中的行数,m是列数。

编辑以回应评论。 我对此并不满意,但是在阅读您的查询后,我相信它会找到与另一个邮政编码有一定距离的所有邮政编码。 好像没有使用第三个笛卡尔积(位置a),因此您可以将查询减少为:

SELECT o.zip_code
FROM locations z, locations o

WHERE z.zip_code = #{zip_code}
AND (3956 * (2 * ASIN(SQRT(
        POWER(SIN(((z.latitude-o.latitude)*0.017453293)/2),2) +
        COS(z.latitude*0.017453293) *
        COS(o.latitude*0.017453293) *
        POWER(SIN(((z.longitude-o.longitude)*0.017453293)/2),2)
    )))) <= #{distance}

但这仍然有一个笛卡尔积。 如果我们能摆脱它,那就更好了:

SELECT zip_code
FROM locations

WHERE (3956 * (2 * ASIN(SQRT(
        POWER(SIN((((SELECT latitude FROM locations WHERE zip_code = #{zip_code})-latitude)*0.017453293)/2),2) +
        COS((SELECT latitude FROM locations WHERE zip_code = #{zip_code})*0.017453293) *
        COS(latitude*0.017453293) *
        POWER(SIN((((SELECT longitude FROM locations WHERE zip_code = #{zip_code})-longitude)*0.017453293)/2),2)
    )))) <= #{distance}

MySQL可能会很好地对其进行优化

  • z保存使用#{zip_code}(参考点)查找的记录

  • a与z相同的记录

  • o包含#{distance}地理距离内的所有记录

简而言之:

它会找到以z为半径#{distance}的圆的所有邮政编码

顺便说一下,3956是地球半径(以英里为单位)(大约),因此您得到的结果将以英里为单位;)

如果您对此感兴趣,可以在http://www.movable-type.co.uk/scripts/gis-faq-5.1.html上阅读更多内容

似乎它试图选择邮政编码$ {zip_code}的#{distance}内的所有邮政编码。

我认为他的帖子很好地解释了余弦定律用于此确切目的的方法: http : //blog.cleverly.com/archive/2000-03.html

z,o和a是别名,因为同一张表自身连接了3次。

这些是表名的简写,因此不用键入locations.zip_code它缩写为a.zip_code

在此示例中也有帮助,因为从3次中选择了同一张表。

这些字母是表别名,它们本质上是SQL开发人员为位置表指定的昵称。 相同的位置表使用三个不同的名称连接在一起,因为它是一个用于在位置表的不同用途之间进行区分的表

位置已重命名为z,位置已重命名为o,位置已重命名为a

将z更改为location1,将o更改为location2,将a更改为location3,如果这有助于您阅读SQL

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM