0

我有餐桌位

place_id | city | country_code | zipcode | lat | lon

现在我想显示距离 A 地点 25 英里以内的地点。地点 A 的 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?

4

3 回答 3

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;
于 2012-08-03T06:49:33.827 回答
0

从子查询中派生一个新表并与原始表进行连接,例如

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

现在您可以将子查询替换为“new_lat”列。

于 2012-08-03T06:48:50.217 回答
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;
于 2012-08-03T06:53:12.903 回答