You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL计算列应用:如何筛选距用户位置≤50km的表数据?

解决MySQL筛选用户50公里范围内数据的问题

嘿,这事儿好办!你只需要把球面距离的计算逻辑直接加到MySQL的WHERE条件里就行,用你熟悉的Active Record语法就能实现。我给你写好补充的代码,顺便解释下细节:

完整的过滤逻辑代码

$currentLatitude = 10.999;
$currentLongitude = 23.354;
$maxDistance = 50; // 最大距离(公里)

$this->db->select('latitude, longitude');
$this->db->from('table');

// 核心:添加距离过滤条件(使用Haversine公式计算球面距离)
$this->db->where("(6371 * acos(cos(radians(?)) * cos(radians(latitude)) * cos(radians(longitude) - radians(?)) + sin(radians(?)) * sin(radians(latitude)))) <= ?", [
    $currentLatitude,
    $currentLongitude,
    $currentLatitude,
    $maxDistance
]);

// 执行查询
$result = $this->db->get()->result();

关键细节说明

  • 6371是地球的平均半径(单位:公里),如果需要用英里计算,替换成3956即可;
  • 用参数绑定(?占位符)传递变量,能有效避免SQL注入风险,这是开发中的最佳实践;
  • 括号内的是Haversine公式的MySQL实现,专门用于计算两个经纬度点之间的球面直线距离,结果直接和50公里阈值比较。

大表查询优化建议

如果你的表数据量很大,直接计算所有行的距离会比较慢,可以先做一层粗略范围过滤,缩小计算范围后再算精确距离:

// 先筛选纬度/经度的粗略范围(±0.45度约等于50公里左右的范围)
$this->db->where('latitude BETWEEN ? AND ?', [$currentLatitude - 0.45, $currentLatitude + 0.45]);
$this->db->where('longitude BETWEEN ? AND ?', [$currentLongitude - 0.45, $currentLongitude + 0.45]);

// 再添加精确距离过滤
$this->db->where("(6371 * acos(cos(radians(?)) * cos(radians(latitude)) * cos(radians(longitude) - radians(?)) + sin(radians(?)) * sin(radians(latitude)))) <= ?", [
    $currentLatitude,
    $currentLongitude,
    $currentLatitude,
    $maxDistance
]);

如果你已经有自己的距离计算方法,直接替换WHERE条件里的距离计算部分即可,只要保证最终结果是公里数,且和$maxDistance比较就行。

内容的提问来源于stack exchange,提问作者dkum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:51:55