2012-08-03 29 views
0

我有表的地方查詢中有兩個相同的子查詢 - 如何使它們成爲1?

place_id | city | country_code | zipcode | lat | lon 

現在我想說明的地方A. A地點25英里範圍內的地方已place_id 1.

SELECT * 
FROM `places` 
WHERE (3959 * acos(cos(radians((SELECT lat FROM places WHERE place_id=1))) * cos(radians(lat)) * cos(radians(lon) - radians((SELECT lon FROM places WHERE place_id=1))) + sin(radians((SELECT lat FROM places WHERE place_id=1))) * sin(radians(lat)))) < 25; 

該工程確定,但有兩個同樣的子查詢

SELECT lat FROM places WHERE place_id=1 

是否可以優化該查詢不能有兩個相同的子查詢,但讓他們變成1?

+0

如果你想聽到那些「MySQL的從來沒有得到的好東西」的評論:查詢作爲輸出看看「公用表表達式」或CTE,他們在MSSQL和Oracle可供選擇 - 它們是甜 - 甜syntacti c糖。 – 2012-08-03 06:52:39

回答

2

您的三個子查詢將針對外部表中的每一行執行。

你可以做的是那些子查詢轉換爲單個JOIN這將僅適用於整個查詢執行一次,以便找到的place_id 1的緯度和經度:

SELECT a.* 
FROM places a 
JOIN (SELECT lat, lon FROM places WHERE place_id = 1) b ON 
     (3959 * acos(cos(radians(b.lat)) * cos(radians(a.lat)) * cos(radians(a.lon) - radians(b.lon)) + sin(radians(b.lat)) * sin(radians(a.lat)))) < 25; 
+0

tnx,我不知道我可以用這種方式加入。 – JohnyFree 2012-08-03 21:28:10

0

從子查詢派生一個新表,並與原有的表連接,像

SELECT * 
FROM places p, (SELECT lat AS new_lat FROM places WHERE place_id = 1) l 
WHERE blah blah 

現在你可以替換列「new_lat」子查詢。

0

可以使用可變@var_lon緩存

SELECT * 
FROM `places` 
WHERE (3959 * acos(cos(radians((SELECT lat FROM places WHERE place_id=1))) * cos(radians(lat)) * cos(radians(lon) - radians((SELECT @var_lon := lon FROM places WHERE place_id=1))) + sin(radians(@var_lon)) * sin(radians(lat)))) < 25; 
相關問題