ThinkPHP+MySQL查询数据的时候计算两个经纬度之间的距离并根据距离进行筛选

原需求实现说明

新增了一个按距离进行筛选的需求。需要把查询代码做如下修改

php 复制代码
    /**
     * 求职意向
     * @return void
     * @throws \think\exception\DbException
     */
    public function get_lists(){
        $request = $this->request->get();
        if(empty($request['lng']) || empty($request['lat'])){
            $this->error('位置信息错误');
        }
        $where = [];
        //筛选城市
        if(!empty($request['city'])){
            $where['p.city'] = array('eq',$request['city']);
        }
        //筛选姓名或者岗位名
        if(!empty($request['keywords'])){
            $where['r.name|c.name'] = array('like','%'.$request['keywords'].'%');
        }
        //筛选工种
        if(!empty($request['gongzhong'])){
            $where['p.gongzhong'] = array('eq',$request['gongzhong']);
        }
        //筛选性别
        if(isset($request['sex']) && in_array($request['sex'],[0,1])){
            $where['r.sex'] = array('eq',$request['sex']);
        }

        //筛选距离
        $sql = '';
        if(!empty($request['distance'])){
            $sql = "ROUND(
                    6378.138 * 2 * ASIN(
                        SQRT(
                            POW(SIN((".$request['lat']." * PI() / 180 - p.lat * PI() / 180) / 2), 2) +
                            COS(".$request['lat']." * PI() / 180) * COS(p.lat * PI() / 180) * POW(SIN((".$request['lng']." * PI() / 180 - p.lng * PI() / 180) / 2), 2)
                        )
                    ) * 1000
                ) < ".$request['distance'];
        }
        //最高学历筛选
        if(!empty($request['zuigaoxueli'])){
            $where['r.zuigaoxueli'] = array('eq',$request['zuigaoxueli']);
        }
        $lists = PurposeModel::alias('p')
            ->join('user u','p.user_id = u.id')
            ->join('resume r','p.user_id = r.user_id')
            ->join('category c','p.category_id = c.id')
            //根据生日计算年领(YEAR(CURDATE()) - YEAR(birthday)) AS age 根据经纬度计算距离
            ->field('p.user_id,r.name,u.avatar,(YEAR(CURDATE()) - YEAR(birthday)) AS age,r.sex,r.zuigaoxueli,c.name as category_name,p.gongzhong,p.work_begin,p.work_end,p.rest_begint,p.rest_end,p.city,p.address,'.getDistanceBuilder($request['lat'], $request['lng']))
            ->where($where)
            ->where($sql)
            ->order('distance asc')
            ->paginate();
        $this->success('获取成功',$lists);
    }

得到的SQL如下

sql 复制代码
SELECT 
    p.user_id,
    r.name,
    u.avatar,
    (YEAR(CURDATE()) - YEAR(birthday)) AS age,
    r.sex,
    c.name AS category_name,
    p.gongzhong,
    p.work_begin,
    p.work_end,
    p.rest_begint,
    p.rest_end,
    p.city,
    p.address,
    ROUND(
        6378.138 * 2 * ASIN(
            SQRT(
                POW(SIN((34.781089 * PI() / 180 - p.lat * PI() / 180) / 2), 2) +
                COS(34.781089 * PI() / 180) * COS(p.lat * PI() / 180) * POW(SIN((113.61261 * PI() / 180 - p.lng * PI() / 180) / 2), 2)
            )
        ) * 1000
    ) AS distance
FROM 
    `fa_purpose` `p`
INNER JOIN 
    `fa_user` `u` ON `p`.`user_id` = `u`.`id`
INNER JOIN 
    `fa_resume` `r` ON `p`.`user_id` = `r`.`user_id`
INNER JOIN 
    `fa_category` `c` ON `p`.`category_id` = `c`.`id`
WHERE 
    `p`.`city` = '郑州'  
    AND (`r`.`name` LIKE '%无人机%' OR `c`.`name` LIKE '%无人机%')
    AND `p`.`gongzhong` = '1'
    AND `r`.`sex` = '0'
    AND ROUND(
        6378.138 * 2 * ASIN(
            SQRT(
                POW(SIN((34.781089 * PI() / 180 - p.lat * PI() / 180) / 2), 2) +
                COS(34.781089 * PI() / 180) * COS(p.lat * PI() / 180) * POW(SIN((113.61261 * PI() / 180 - p.lng * PI() / 180) / 2), 2)
            )
        ) * 1000
    ) < 500
ORDER BY 
    distance ASC
相关推荐
计算机学姐1 小时前
基于微信小程序的民宿预订管理系统
java·vue.js·spring boot·后端·mysql·微信小程序·小程序
web2u4 小时前
MySQL 中如何进行 SQL 调优?
java·数据库·后端·sql·mysql·缓存
新知图书6 小时前
MySQL用户授权、收回权限与查看权限
数据库·mysql·安全
文城5216 小时前
Mysql存储过程(学习自用)
数据库·学习·mysql
沉默的煎蛋6 小时前
MyBatis 注解开发详解
java·数据库·mysql·算法·mybatis
C语言扫地僧6 小时前
MySQL 事务及MVCC机制详解
数据库·mysql
小镇cxy6 小时前
MySQL事物,MVCC机制
数据库·mysql
雾里看山7 小时前
【MySQL】 库的操作
android·数据库·笔记·mysql
꧁瀟洒辵1恛꧂8 小时前
从新手到高手的蜕变:MySQL 视图进阶全攻略
数据库·mysql
doubt。20 小时前
【BUUCTF】[RCTF2015]EasySQL1
网络·数据库·笔记·mysql·安全·web安全