0
点赞
收藏
分享

微信扫一扫

sql距离查询,多多指教

ROUND(
6378.138 * 2 * ASIN(
SQRT(
POW(
SIN(
(
用户纬度 * PI() / 180 - 纬度字段名* PI() / 180
) / 2
),
2
) + COS(用户纬度 * PI() / 180) * COS(纬度字段名 * PI() / 180) * POW(
SIN(
(
用户经度 * PI() / 180 - 经度字段名 * PI() / 180
) / 2
),
2
)
)
) * 1000
) AS juli

创建函数:
drop function if exists calc_rice;
create function calc_rice(lng1 varchar(20), lat1 varchar(20), lng2 varchar(20), lat2 varchar(20)) returns int
begin
return ROUND(6378.138 * 2 * ASIN(SQRT(
POW(SIN(( lat1 * PI() / 180 - lat2 * PI() / 180 ) / 2), 2) +
COS( lat1 * PI() / 180) * COS(lat2 * PI() / 180) *
POW(SIN(( lng1 * PI() / 180 - lng2 * PI() /180) / 2), 2)
)) * 1000 );
end ;
注释:
(当前经度, 当前纬度, 需要比对的经度,需要比对的纬度)
测试
select calc_rice(127, 33, 127, 34) as rice

如果创建时报错:
This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its de
请在root账号下执行:
set global log_bin_trust_function_creators=TRUE;

SELECT
id,
name,
lat,
lng,

ROUND(
6378.138 * 2 * ASIN(
SQRT(
POW(
SIN(
(
40.042307 * PI() / 180 - lat * PI() / 180
) / 2
),
2
) + COS(40.042307 * PI() / 180) * COS(lat * PI() / 180) * POW(
SIN(
(
116.317205 * PI() / 180 - lng * PI() / 180
) / 2
),
2
)
)
) * 1000
) AS juli
FROM
fa_shop
ORDER BY
juli DESC

$sql =" SELECT   id, name,  lat,  lng,  ";
$sql .=latlngfield("40.042307", "116.317205") ;
$sql .= " FROM fa_shop ORDER BY juli DESC";
//距离排序 字段生成
function latlngfield($lat, $lng,$latfield="lat", $lngfield="lng", $returnfield="juli") {
$sql=" ROUND( 6378.138 * 2 * ASIN( SQRT( POW( SIN( ( ";
$sql.= $lat." * PI() / 180 - ".$latfield." * PI() / 180 ) / 2 ), 2 ) + COS( ";
$sql.= $lat." * PI() / 180) * COS( ".$latfield." * PI() / 180) * POW( SIN( ( ";
$sql.= $lng." * PI() / 180 - ". $lngfield." * PI() / 180 ) / 2 ), 2 ) ) ) * 1000 ) AS " .$returnfield."";
return $sql;
}

tp用法
//距离排序 字段生成

function latlngfield($lat, $lng,$latfield="lat", $lngfield="lng", $returnfield="juli") {
$sql=" ROUND( 6378.138 * 2 * ASIN( SQRT( POW( SIN( ( ";
$sql.= $lat." * PI() / 180 - ".$latfield." * PI() / 180 ) / 2 ), 2 ) + COS( ";
$sql.= $lat." * PI() / 180) * COS( ".$latfield." * PI() / 180) * POW( SIN( ( ";
$sql.= $lng." * PI() / 180 - ". $lngfield." * PI() / 180 ) / 2 ), 2 ) ) ) * 1000 ) AS " .$returnfield."";
return $sql;
}
Db::name("user")
->field("id, name, lat, lng,".latlngfield("40.042307", "116.317205"))
->where(["juli","<","1000000"])
->order("juli desc")
->select();

php算距离

/**
* 根据经纬度算距离,返回结果单位是公里,先纬度,后经度
* @param $lat1
* @param $lng1
* @param $lat2
* @param $lng2
* @return float|int
*/
public function GetDistance($lat1, $lng1, $lat2, $lng2)
{
$EARTH_RADIUS = 6378.137;

$radLat1 = $this->rad($lat1);
$radLat2 = $this->rad($lat2);
$a = $radLat1 - $radLat2;
$b = $this->rad($lng1) - $this->rad($lng2);
$s = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2)));
$s = $s * $EARTH_RADIUS;
$s = round($s * 10000) / 10000;

return $s;
}

private function rad($d)
{
return $d * M_PI / 180.0;
}



举报

相关推荐

sql 查询

SQL查询

sql连接查询

SQL嵌套查询

SQL子查询

SQL 高级查询

0 条评论