我的半径搜索有一些问题。 我有一张包含邮政编码、地名和地理坐标的表格(基于 OpenGeoDB)。
这是我的 SQL 命令:
SELECT main.zc_zip,
(ACOS(
SIN(RADIANS(main.zc_lat)) * SIN(RADIANS(geo.zc_lat))
+ COS(RADIANS(main.zc_lat)) * COS(RADIANS(geo.zc_lat))
* COS(RADIANS(main.zc_lon) - RADIANS(geo.zc_lon))
) * 6380) AS `distance`
FROM tx_sdfilmbase_geodb main
LEFT JOIN tx_sdfilmbase_geodb geo ON geo.zc_location_name LIKE '%frauenfeld%'
WHERE
(ACOS(
SIN(RADIANS(main.zc_lat)) * SIN(RADIANS(geo.zc_lat))
+ COS(RADIANS(main.zc_lat)) * COS(RADIANS(geo.zc_lat))
* COS(RADIANS(main.zc_lon) - RADIANS(geo.zc_lon))
) * 6380) < 20
AND main.disabled=0
ORDER BY `distance` ASC
我得到了 Frauenfeld 周围 20 公里半径范围内所有地点的结果。 但是,对于名为“frauenfeld”的位置,我没有得到任何结果 - 即我得到了所有周围的地方,但没有搜索到的地方本身。
我必须如何更改 SQL 才能同时获取位置本身? 我尝试了不同的东西,但结果总是一样的......
很乐意提供一些提示。
问候 斯特凡
编辑以回答 ypercube 和 Matt Gibson 的评论:
此时数据库表中的所有条目都已禁用=0。
在许多其他结果中,我得到以下结果(zip、距离):
- 8552 3.7661608052471
- 8500 4.184731709915
- 8523 4.9298917004071
- 9548 4.9771821340396
Frauenfeld 的邮政编码:8500、8501、8502 和 8503。
结果中缺少的条目将是(zip,距离):
- 8500 0
- 8501 0
- 8502 0
- 8503 0
然而,地理数据库中的数据是正确的( zip 、地点、纬度、经度):
- 8503 弗劳恩菲尔德 47.557707 8.897367
- 8502 弗劳恩菲尔德 47.557707 8.897367
- 8501 弗劳恩菲尔德 47.557707 8.897367
- 8500 弗劳恩菲尔德 47.557707 8.897367
编辑回复 kuru kuru pa 的回答:
感谢您的回复!
答案现在看起来像这样(zc_location_name、zc_zip、禁用、距离):
Frauenfeld 8500 0 NULL
Frauenfeld 8503 0 NULL
Frauenfeld 8502 0 NULL
Frauenfeld 8501 0 NULL
Gerlikon 8500 0 4.18473170991499
为什么是NULL而不是0?有什么猜测吗? :-) 顺便说一句:每个结果都列出了 4 次(我只发布了一次)。
最佳答案
运行这个查询:
SELECT
main.zc_zip,
main.disabled,
(ACOS(
SIN(RADIANS(main.zc_lat)) * SIN(RADIANS(geo.zc_lat))
+ COS(RADIANS(main.zc_lat)) * COS(RADIANS(geo.zc_lat))
* COS(RADIANS(main.zc_lon) - RADIANS(geo.zc_lon))
) * 6380) AS `distance`
FROM tx_sdfilmbase_geodb main
LEFT JOIN tx_sdfilmbase_geodb geo ON geo.zc_location_name LIKE '%frauenfeld%'
WHERE main.zc_zip in(8500, 8501, 8502, 8503)
ORDER BY `distance` ASC
然后评估distance
和disabled
的结果。您的功能或禁用的值(value)可能不是您期望的那样。
编辑(响应距离字段的空结果)
SELECT
main.zc_zip,
main.disabled,
(ACOS(
SIN(RADIANS(isnull(main.zc_lat,0))) * SIN(RADIANS(isnull(geo.zc_lat,0)))
+ COS(RADIANS(isnull(main.zc_lat,0))) * COS(RADIANS(isnull(geo.zc_lat,0)))
* COS(RADIANS(isnull(main.zc_lon,0)) - RADIANS(isnull(geo.zc_lon,0)))
) * 6380) AS `distance`
FROM tx_sdfilmbase_geodb main
LEFT JOIN tx_sdfilmbase_geodb geo ON geo.zc_location_name LIKE '%frauenfeld%'
WHERE main.zc_zip in(8500, 8501, 8502, 8503)
ORDER BY `distance` ASC
或
SELECT
main.zc_zip,
main.disabled,
isnull(
(ACOS(
SIN(RADIANS(main.zc_lat)) * SIN(RADIANS(geo.zc_lat))
+ COS(RADIANS(main.zc_lat)) * COS(RADIANS(geo.zc_lat))
* COS(RADIANS(main.zc_lon) - RADIANS(geo.zc_lon))
)
,0) * 6380) AS `distance`
FROM tx_sdfilmbase_geodb main
LEFT JOIN tx_sdfilmbase_geodb geo ON geo.zc_location_name LIKE '%frauenfeld%'
WHERE main.zc_zip in(8500, 8501, 8502, 8503)
ORDER BY `distance` ASC
或者替代使用 ISNULL()
将原来的 WHERE 修改为“WHERE distance < 20 OR distance is null”
关于mysql - 使用 LEFT JOIN 进行半径搜索的 SQL 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7429075/