【发布时间】:2015-04-14 06:57:18
【问题描述】:
我有下表:
id user_id recorded latitude longitude speed note_type details image_url
1 10 3/29/2013 33.77701316 -84.39004377 -1 11 Test 2ecc2e36c3e1a512d349f9b407fb281e-2013-03-29-16-15-..
我正在尝试找到一种方法将以下查询组合成一个完整的查询,该查询将为我提供与每个单独查询匹配的所有记录(每个单独的查询都可以正常工作,只是无法弄清楚如何组合它们):
SELECT id, ( 3959 * acos( cos( radians(User_Input_Longitude) ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians(User_Input_Latitude) ) + sin( radians(User_Input_Longitude) ) * sin( radians( latitude ) ) ) ) AS distance
FROM note HAVING distance < User_Input_Distance
ORDER BY distance LIMIT 0 , 1000
SELECT details
FROM note
WHERE CHAR_LENGTH(details) > User_Input_CharacterLength
SELECT DISTINCT details
FROM note;
SELECT DISTINCT image_url
FROM note;
所以基本上我需要一个查询,将基于 long/lat 点的距离与用户定义的 long/lat 点和用户定义的距离进行比较,检查详细信息字段的字符长度,然后最后只记录具有不同数据的记录details 和 image_urls(很多 image_urls 和 details 都是空的,所以我一直在使用 distinct 来查找那些实际上有数据的人,不确定这是否是正确的方法)。
就像我之前说的,这些查询中的每一个现在都是单独工作的,但不幸的是我在 mySql 中没有足够的技能来以智能的方式组合它们。
任何关于这方面的建议都会很棒。
【问题讨论】:
-
HAVING distance < User_Input_Distance应该是WHERE distance < User_Input_Distance,对于初学者来说。除了你需要更新你的表架构,因为你需要执行一些joins,并且需要知道这些关系。 -
@lp_ 给出的答案涵盖了构建 MySQL 查询的正确方法。您可能还想考虑简化
distance子句,并简单地为“边界正方形”选择一个(可能)稍大的结果集,然后在您的 PHP 中拒绝不符合更精确极坐标的结果。这样可以减少 CPU 负载,还可以利用longitude和latitude列上的索引,尤其是在表很大的情况下。 HTH -
@GavinJackson 好点。稍微澄清一下:你说做一个更简单的查询来检查距离,这基本上会占用更大的区域,然后在我的 php 文件过滤器中更接近以减少负载。有道理,因为我认为这个查询在计算上会很昂贵。我的表有大约 1k 个条目,但是“利用经度和纬度列上的索引”是什么意思?
-
@NASAIntern 目前我认为查询需要为每一行计算您的
distance,因为如果不进行极坐标计算,它无法知道哪些行将符合中间HAVING条款。如果您根据“边界正方形”进行 SELECT,通过预先计算 max_lat、min_lat、max_lng、min_lng,作为“User_Latitude”、“User_Longitude”和“User_Distance”的函数,然后是(latitude BETWEEN (min_lat AND max_lat))AND(longitude BETWEEN min_lng AND max_lng )的 WHERE 子句如果纬度和经度列被索引,则只需要读取符合条件的行。