簡體   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