使用substring函数的结果来计算多列的值

时间:2012-10-04 12:11:00

标签: mysql substring haversine

我正试图找到一个长和纬度的最近点。哪个工作正常,我有单独的值存储在我的数据库中,但我有一个管道字符串,我可以用子字符串索引拆分。但是,当我尝试在我的选择查询中组合这些功能时,我没有任何乐趣。

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(longlat, '|', 1), '|', -1) as 'lat',
SUBSTRING_INDEX(SUBSTRING_INDEX(longlat, '|', 2), '|', -1) as 'lng',
title,
( 6371 * acos( cos( radians(51.527351) ) * cos( radians( 'lat') ) * cos( radians( 'lng' ) - radians(0.765544) ) + sin( radians(51.527351) ) * sin( radians( 'lat' ) ) ) ) AS distance 
FROM locations HAVING distance < 500
ORDER BY distance
LIMIT 0 , 20

任何人都能解释一下吗?

2 个答案:

答案 0 :(得分:1)

  

radians( 'lat')

在查询的这一部分中,'lat'是一个字符串,而不是列名或类似名称。将该字符串传递给radians时,它将转换为数字,在本例中为零。所以你将0转换为弧度。

您不能使用一列作为计算另一列值的输入。您要么必须重复表达式,要么使用这样的子查询:

SELECT lat, lng, title,
  (6371 * acos(cos(radians(51.527351)) *
   cos(radians(lat)) * cos(radians(lng) - radians(0.765544)) +
   sin(radians(51.527351)) * sin(radians(lat)))
  ) AS distance
FROM
  (SELECT title,
     SUBSTRING_INDEX(SUBSTRING_INDEX(longlat, '|', 1), '|', -1) + 0 as lat,
     SUBSTRING_INDEX(SUBSTRING_INDEX(longlat, '|', 2), '|', -1) + 0 as lng
   FROM locations
  ) AS sub
HAVING distance < 500
ORDER BY distance
LIMIT 0 , 20

答案 1 :(得分:0)

这是我的解决方案,重复查询。我没有机会测试不同解决方案的基准测试,但子查询解决方案更令人愉快

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(longlat, '|', 1), '|', -1) as 'latitude',
       SUBSTRING_INDEX(SUBSTRING_INDEX(longlat, '|', 2), '|', -1) as 'longitude',
(
  3959 * acos(
    cos(radians({MYLAT})) * cos(radians(SUBSTRING_INDEX(SUBSTRING_INDEX(longlat, '|', 1), '|', -1)))
    * cos(radians(SUBSTRING_INDEX(SUBSTRING_INDEX(longlat, '|', 2), '|', -1))) - radians({MYLONG}) + sin(radians({MYLAT})) 
    * sin( radians(SUBSTRING_INDEX(SUBSTRING_INDEX(longlat, '|', 1), '|', -1)))
  )
)
AS distance,
title

FROM locations
ORDER BY distance
LIMIT 0 , 20

原来我现在到处都会使用这个等式,所以很高兴把它钉在上面:)

我使用平均值3959作为地球的半径,但是我想知道我是否可以更好地在不同的全球位置使用某种区域纬度。