【问题标题】:mySql - Finding customers near a specific citymySql - 在特定城市附近寻找客户
【发布时间】:2019-09-19 14:07:23
【问题描述】:

我正在尝试制作一个查询以查找给定城市和州 X 英里内的所有客户,基本上使用以下表格结构:

Users Table
-----------
ID

PersonsName

ZipCode

Zipcodes Table (contains all ZIPs in the US)
--------------------------------------------
ID

ZipCode

City

State

latitude

longitude

如果我已经知道我感兴趣的城市的纬度/经度,就很容易找到附近的用户,如以下查询所示:

SELECT ID from Users u
JOIN Zipcodes z1 ON u.zipcode = z1.zipcode
WHERE 
COS(SIN(PI()*z1.latitude/180.0)*SIN(PI()*[desired latitude]/180.0)+COS(PI()*z1.latitude/180.0)*COS(PI()*[desired latitude]/180.0)*COS(PI()*[desired longitude]/180.0-PI()*z1.longitude/180.0))*3963.0 <= [desired distance]

但是,我希望能够使用城市名称和州缩写来方便输入,然后让查询使用该 lat/lng 进行距离比较。

我想我可以写两个查询,第一个获取所需城市的 lat/lng,然后第二个使用结果查找返回的 lat/lng 对的一定距离内的用户,但它可以是组合成一个查询,获取城市匹配的正确纬度/经度,然后在 WHERE 子句中的距离计算中使用它?

无法弄清楚如何制作它以便可以找到城市的纬度/经度,然后在同一个查询中使用距离。

希望我们的一名员工能够简单地输入城市/州和所需的距离,代码会返回所有适用的客户。代码只会获取特定城市的第一个匹配项(大城市的 ZIP 表中可能有很多条目),但这对我们的目的来说很好(因此我们可以只使用第一个匹配项)。

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    我同意地理编码将处理此查询未涵盖的大部分边缘情况,但如果您正在寻找仅使用手头工具的快速而肮脏的修复,我相信以下查询将适合您。

    SELECT ID from Users u
      JOIN Zipcodes z1 ON u.zipcode = z1.zipcode
      join (select latitude as desired_latitude, longitude as desired_longitude from Zipcodes limit 1 where City = '[user input]' and State = '[user input]' limit 1)
    WHERE
      COS(SIN(PI()*z1.latitude/180.0)*SIN(PI()*[desired latitude]/180.0)+COS(PI()*z1.latitude/180.0)*COS(PI()*[desired latitude]/180.0)*COS(PI()*[desired longitude]/180.0-PI()*z1.longitude/180.0))*3963.0 <= [desired distance];
    

    虽然假设您的 User 表中的行数比 Zipcodes 表中的多,但您可能希望将该查询重构为如下所示:

    SELECT ID from Users u
      JOIN (
              select z1.zipcode from Zipcodes z1
              join (select latitude as desired_latitude, longitude as desired_longitude from Zipcodes limit 1 where City = '[user input]' and State = '[user input]' limit 1)
              WHERE COS(SIN(PI()*z1.latitude/180.0)*SIN(PI()*desired_latitude/180.0)+COS(PI()*z1.latitude/180.0)*COS(PI()*desired_latitude/180.0)*COS(PI()*desired_longitude/180.0-PI()*z1.longitude/180.0))*3963.0 <= [desired distance]
           ) as zipsInRange ON u.zipcode = zipsInRange.zipcode;
    

    【讨论】:

      【解决方案2】:

      听起来您可能需要在其中进行一些地理编码,才能将城市名称转换为坐标。有很多好的 API 可用(Google、Algolia、Mapbox 等)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-05-22
        • 1970-01-01
        • 2019-04-21
        • 1970-01-01
        • 2011-06-04
        • 2022-10-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多