MySQL: 如何计算特定半径(经度/纬度)内的中位数
MySQL: How can I calculate the median in a specific radius (longitude / latitude)
我想计算给定坐标在特定半径内的中位数和平均值。
重要的属性是:
- 纬度
- 经度
- 价格
计算平均值的sql命令是:
SELECT avg(price) as average
FROM (SELECT r.*,
( 6371 * acos( cos( radians(37.3541079) ) * cos( radians( ANY_VALUE(`latitude` )) ) * cos( radians( ANY_VALUE(`longitude`) ) - radians(-121.9552356) ) + sin( radians(37.3541079) ) * sin( radians( ANY_VALUE(`latitude`) ) ) ) ) AS distance
FROM `Rental` r
) r
WHERE distance <= 20;
我的问题是如何计算给定坐标和半径内价格的中位数。 MySQL 没有 median() 函数。
编辑:
现在我已经尝试了 Simple way to calculate median with MySQL
中的代码
SELECT AVG(middle_values) AS 'median' FROM (
SELECT t1.price AS 'middle_values' FROM
(
SELECT @row:=@row+1 as `row`, x.price
FROM rental AS x, (SELECT @row:=0) AS r
WHERE 1
-- put some where clause here
ORDER BY x.price
) AS t1,
(
SELECT COUNT(*) as 'count'
FROM rental x
WHERE 1
-- put same where clause here
) AS t2
-- the following condition will return 1 record for odd number sets, or 2 records for even number sets.
WHERE t1.row >= t2.count/2 and t1.row <= ((t2.count/2) +1)) AS t3;
它适用于所有 200'000 条记录,但是当我添加 WHERE distance <= 20
时 mysql - 请求过载。
SELECT AVG(middle_values) AS 'median' FROM (
SELECT t1.price AS 'middle_values' FROM
(
SELECT @row:=@row+1 as `row`, x.price
FROM rental AS x, (SELECT @row:=0) AS r, (SELECT a.*,
( 6371 * acos( cos( radians(37.3541079) ) * cos( radians( ANY_VALUE(`latitude` )) ) * cos( radians( ANY_VALUE(`longitude`) ) - radians(-121.9552356) ) + sin( radians(37.3541079) ) * sin( radians( ANY_VALUE(`latitude`) ) ) ) ) AS distance
FROM `Rental` a
) a
WHERE distance <= 20
-- put some where clause here
ORDER BY x.price
) AS t1,
(
SELECT COUNT(*) as 'count'
FROM rental x, (SELECT a.*,
( 6371 * acos( cos( radians(37.3541079) ) * cos( radians( ANY_VALUE(`latitude` )) ) * cos( radians( ANY_VALUE(`longitude`) ) - radians(-121.9552356) ) + sin( radians(37.3541079) ) * sin( radians( ANY_VALUE(`latitude`) ) ) ) ) AS distance
FROM `Rental` a
) a
WHERE distance <= 20
-- put same where clause here
) AS t2
-- the following condition will return 1 record for odd number sets, or 2 records for even number sets.
WHERE t1.row >= t2.count/2 and t1.row <= ((t2.count/2) +1)) AS t3;
有什么地方失误了吗?
问题在于计算距离的 table 扫描,而不是中位数。
- 将数据放在
TEMPORARY TABLE
中,这样您就不必对其进行 3 次评估(平均值、计数和中位数)。
- 将 "bounding box" 添加到最里面的
WHERE
以将检查限制为 20x20 "square"。
INDEX(latitude)
- 使用
HAVING distance < 20
而不是需要另一个子查询。
我想计算给定坐标在特定半径内的中位数和平均值。
重要的属性是: - 纬度 - 经度 - 价格
计算平均值的sql命令是:
SELECT avg(price) as average
FROM (SELECT r.*,
( 6371 * acos( cos( radians(37.3541079) ) * cos( radians( ANY_VALUE(`latitude` )) ) * cos( radians( ANY_VALUE(`longitude`) ) - radians(-121.9552356) ) + sin( radians(37.3541079) ) * sin( radians( ANY_VALUE(`latitude`) ) ) ) ) AS distance
FROM `Rental` r
) r
WHERE distance <= 20;
我的问题是如何计算给定坐标和半径内价格的中位数。 MySQL 没有 median() 函数。
编辑: 现在我已经尝试了 Simple way to calculate median with MySQL
中的代码SELECT AVG(middle_values) AS 'median' FROM (
SELECT t1.price AS 'middle_values' FROM
(
SELECT @row:=@row+1 as `row`, x.price
FROM rental AS x, (SELECT @row:=0) AS r
WHERE 1
-- put some where clause here
ORDER BY x.price
) AS t1,
(
SELECT COUNT(*) as 'count'
FROM rental x
WHERE 1
-- put same where clause here
) AS t2
-- the following condition will return 1 record for odd number sets, or 2 records for even number sets.
WHERE t1.row >= t2.count/2 and t1.row <= ((t2.count/2) +1)) AS t3;
它适用于所有 200'000 条记录,但是当我添加 WHERE distance <= 20
时 mysql - 请求过载。
SELECT AVG(middle_values) AS 'median' FROM (
SELECT t1.price AS 'middle_values' FROM
(
SELECT @row:=@row+1 as `row`, x.price
FROM rental AS x, (SELECT @row:=0) AS r, (SELECT a.*,
( 6371 * acos( cos( radians(37.3541079) ) * cos( radians( ANY_VALUE(`latitude` )) ) * cos( radians( ANY_VALUE(`longitude`) ) - radians(-121.9552356) ) + sin( radians(37.3541079) ) * sin( radians( ANY_VALUE(`latitude`) ) ) ) ) AS distance
FROM `Rental` a
) a
WHERE distance <= 20
-- put some where clause here
ORDER BY x.price
) AS t1,
(
SELECT COUNT(*) as 'count'
FROM rental x, (SELECT a.*,
( 6371 * acos( cos( radians(37.3541079) ) * cos( radians( ANY_VALUE(`latitude` )) ) * cos( radians( ANY_VALUE(`longitude`) ) - radians(-121.9552356) ) + sin( radians(37.3541079) ) * sin( radians( ANY_VALUE(`latitude`) ) ) ) ) AS distance
FROM `Rental` a
) a
WHERE distance <= 20
-- put same where clause here
) AS t2
-- the following condition will return 1 record for odd number sets, or 2 records for even number sets.
WHERE t1.row >= t2.count/2 and t1.row <= ((t2.count/2) +1)) AS t3;
有什么地方失误了吗?
问题在于计算距离的 table 扫描,而不是中位数。
- 将数据放在
TEMPORARY TABLE
中,这样您就不必对其进行 3 次评估(平均值、计数和中位数)。 - 将 "bounding box" 添加到最里面的
WHERE
以将检查限制为 20x20 "square"。 INDEX(latitude)
- 使用
HAVING distance < 20
而不是需要另一个子查询。