【问题标题】:SQL : Finding nearest point within different radius from given latitude & longitudeSQL:从给定的纬度和经度查找不同半径内的最近点
【发布时间】:2018-09-11 08:02:08
【问题描述】:

到目前为止,我已经能够在同一半径内找到最近的点(本文中的仓库)。 (已经有很多答案的常见问题)。

这是实际代码(不使用多个半径)

$radius = 5; // miles

$q = "
    SELECT DISTINCT 
      warehouse_latitude.post_id,
      warehouse_longitude.meta_value as longitude,
      warehouse_latitude.meta_value as latitude,
      ((ACOS(SIN($latitude * PI() / 180) * SIN(warehouse_latitude.meta_value * PI() / 180) + COS($latitude * PI() / 180) * COS(warehouse_latitude.meta_value * PI() / 180) * COS(($longitude - warehouse_longitude.meta_value) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) AS distance
    FROM {$this->wpdb->postmeta} as warehouse_latitude
      LEFT JOIN {$this->wpdb->postmeta} as warehouse_longitude ON warehouse_latitude.post_id = warehouse_longitude.post_id 
    WHERE warehouse_latitude.meta_key = 'warehouse_latitude' AND warehouse_longitude.meta_key = 'warehouse_longitude'
    HAVING distance < $radius
    ORDER BY distance ASC
    LIMIT 1
";

改为:

我想选择最近的点,但为每个点定义了半径(仓库)。

  • A 点 (9714):半径 5 英里
  • B 点 (9715):半径 2 英里
  • 点 C (9716):半径 10 英里

所以如果 B 点和 C 点在范围内,并且 B 点最近,它应该选择 B 点。

wp_postmeta 表:

meta_id | post_id | meta_key             | meta_value
------------------------------------------------------
324802  | 9714    | warehouse_latitude   | 47.1978754
324809  | 9715    | warehouse_latitude   | 47.2064462
324814  | 9716    | warehouse_latitude   | 47.214434
324803  | 9714    | warehouse_longitude  | -1.54441
324810  | 9715    | warehouse_longitude  | -1.5461347
324815  | 9716    | warehouse_longitude  | -1.565993
324806  | 9714    | warehouse_radius     | 5
324811  | 9715    | warehouse_radius     | 2
324816  | 9716    | warehouse_radius     | 10

架构:

【问题讨论】:

  • 能否以表格的形式添加样本数据,然后显示预期的输出?这是一个标准的 Haversine MySQL 查询,但我在这里看不到您想要的确切内容。
  • Left join x... where x=...inner join x 相同。因此,请将条件移至 on 子句。另外,弧度有什么问题?
  • 这里有什么问题?
  • @Strawberry 当然,我不介意使用弧度,这是我找到的第一个解决方案。
  • @SalmanA 有什么问题吗?它可以在没有 LIMIT 的情况下工作,但我只需要得到一个 :)。

标签: mysql sql wordpress


【解决方案1】:

没有答案。评论太长了...

1  LEFT JOIN warehouse_longitude ON ... -- This is an INNER JOIN because of LINE 3
2  LEFT JOIN warehouse_radius ON ...    -- This is also an INNER JOIN, because of LINE 4 
3 WHERE warehouse_longitude.meta_key = 'warehouse_longitude' 
4   AND warehouse_radius.meta_key = 'warehouse_radius'

所以你不妨把这些写成 INNER JOIN 开始。

【讨论】:

  • 感谢您的意见。我会尝试并更新我的答案:)。
【解决方案2】:

所以这里是解决方案(从上一个查询更新)。

如果您有更有效/更易读的方法来计算距离,请不要介意再给出一个答案。

SELECT DISTINCT 
  warehouse_latitude.post_id,
  warehouse_longitude.meta_value as longitude,
  warehouse_latitude.meta_value as latitude,
  warehouse_radius.meta_value as radius,
  ((ACOS(SIN($latitude * PI() / 180) * SIN(warehouse_latitude.meta_value * PI() / 180) + COS($latitude * PI() / 180) * COS(warehouse_latitude.meta_value * PI() / 180) * COS(($longitude - warehouse_longitude.meta_value) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) AS distance
FROM {$this->wpdb->postmeta} as warehouse_latitude
  LEFT JOIN {$this->wpdb->postmeta} as warehouse_longitude ON warehouse_latitude.post_id = warehouse_longitude.post_id
  LEFT JOIN {$this->wpdb->postmeta} as warehouse_radius ON warehouse_latitude.post_id = warehouse_radius.post_id 
WHERE warehouse_latitude.meta_key = 'warehouse_latitude' AND warehouse_longitude.meta_key = 'warehouse_longitude' AND warehouse_radius.meta_key = 'warehouse_radius'
HAVING distance < (radius * 0.62)
ORDER BY distance ASC
LIMIT 1

我在半径值上添加了一个连接:

LEFT JOIN {$this->wpdb->postmeta} as warehouse_radius ON warehouse_latitude.post_id = warehouse_radius.post_id 

WHERE 语句中的另一个条件:

AND warehouse_radius.meta_key = 'warehouse_radius'

因此:

我可以将 HAVING 语句更新为:

HAVING distance < (radius * 0.62) -- Km to Miles

【讨论】:

  • 尝试使用HAVING distance &lt; (warehouse_radius.radius * 0.62)
  • 我当然可以。实际上,我确实在返回的响应中使用了这个别名(因为我以后可能会使用它;)。一样一样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多