Select 根据邮政编码及其半径在 MySQL 中记录
Select records based on the postal code and it's radius in MySQL
下面是我的postal
table和一些记录。事实上,这个 table 包含所有城市和所有邮政编码。
id city postalcode latitude longitude
1 Drogteropslagen 7705 PA 52.61666700 6.50000000
2 Coevorden 7740 AA 52.66666700 6.75000000
3 Emmen 7812 TN 52.78333300 6.90000000
4 Emmer-Compascuum 7881 PZ 52.81666700 7.05000000
5 Nieuw-Dordrecht 7885 AA 52.75000000 6.96666700
下面是我的 company
table 及其邮政编码和每家公司能够提供服务的半径(以公里为单位)。
id company_name city postalcode radius latitude longitude
1 A Emmen 7812 TN 10 52.78333300 6.90000000
2 B Nieuw-Dordrecht 7885 AA 5 52.75000000 6.96666700
3 C Drogteropslagen 7705 PA 25 52.61666700 6.50000000
4 D Foxhol 9607 PR 0 53.16666700 6.71666700
5 E Westerbroek 9608 PA 15 53.18333300 6.68333300
我想 select 有特定邮政编码的公司,例如7740 AA
居住在邮政编码加上公司半径范围内。请注意,特定的邮政编码可能并不总是存在于 company
table 中,但始终存在于 postal
table 中。如何向 select 那些公司编写 sql 查询。
此方法在包含感兴趣公司的单个记录的子查询与包含每个公司的子查询之间执行 CROSS JOIN
。该查询使用 Haversine 公式计算两家公司之间的距离(以公里为单位)(您可以阅读更多相关内容 here)。
此查询用于获取邮政编码 7740 AA
.
半径 20 公里范围内的所有公司
SELECT t2.company_name,
(6371 * acos(cos(radians(t1.lat1)) * cos(radians(t2.lat2))
* cos(radians(t2.lng2) - radians(t1.lng1)) + sin(radians(t1.lat1)) * sin(radians(t2.lat2)))) AS distance
FROM
(
SELECT p.latitude AS lat1, p.longitude AS lng1
FROM postal p
WHERE p.postalcode = '7740 AA'
) t1
CROSS JOIN
(
SELECT c.company_name, p.latitude AS lat2, p.longitude AS lng2
FROM company c INNER JOIN postal p
ON c.postalcode = p.postalcode
) t2
HAVING distance < 20
Tim Biegeleisen 的询问启发我找到了如下可行的解决方案。
SELECT t2.company_name,
(6371 * acos(cos(radians(t1.lat1)) * cos(radians(t2.lat2))
* cos(radians(t2.lng2) - radians(t1.lng1)) + sin(radians(t1.lat1)) *
sin(radians(t2.lat2)))) AS distance,
t2.radius
FROM
(
SELECT p.latitude AS lat1, p.longitude AS lng1
FROM postal p
WHERE p.postalcode = '7894 AA'
) t1
CROSS JOIN
(
SELECT c.company_name, p.latitude AS lat2, p.longitude AS lng2,
c.radius
FROM company c
INNER JOIN postal p
ON c.postalcode = p.postalcode
) t2
HAVING distance < t2.radius
通过上述查询,距离不会与固定的公里数(例如20或50公里)进行比较,而是与每个公司的动态半径(以公里为单位)进行比较。
下面是我的postal
table和一些记录。事实上,这个 table 包含所有城市和所有邮政编码。
id city postalcode latitude longitude
1 Drogteropslagen 7705 PA 52.61666700 6.50000000
2 Coevorden 7740 AA 52.66666700 6.75000000
3 Emmen 7812 TN 52.78333300 6.90000000
4 Emmer-Compascuum 7881 PZ 52.81666700 7.05000000
5 Nieuw-Dordrecht 7885 AA 52.75000000 6.96666700
下面是我的 company
table 及其邮政编码和每家公司能够提供服务的半径(以公里为单位)。
id company_name city postalcode radius latitude longitude
1 A Emmen 7812 TN 10 52.78333300 6.90000000
2 B Nieuw-Dordrecht 7885 AA 5 52.75000000 6.96666700
3 C Drogteropslagen 7705 PA 25 52.61666700 6.50000000
4 D Foxhol 9607 PR 0 53.16666700 6.71666700
5 E Westerbroek 9608 PA 15 53.18333300 6.68333300
我想 select 有特定邮政编码的公司,例如7740 AA
居住在邮政编码加上公司半径范围内。请注意,特定的邮政编码可能并不总是存在于 company
table 中,但始终存在于 postal
table 中。如何向 select 那些公司编写 sql 查询。
此方法在包含感兴趣公司的单个记录的子查询与包含每个公司的子查询之间执行 CROSS JOIN
。该查询使用 Haversine 公式计算两家公司之间的距离(以公里为单位)(您可以阅读更多相关内容 here)。
此查询用于获取邮政编码 7740 AA
.
SELECT t2.company_name,
(6371 * acos(cos(radians(t1.lat1)) * cos(radians(t2.lat2))
* cos(radians(t2.lng2) - radians(t1.lng1)) + sin(radians(t1.lat1)) * sin(radians(t2.lat2)))) AS distance
FROM
(
SELECT p.latitude AS lat1, p.longitude AS lng1
FROM postal p
WHERE p.postalcode = '7740 AA'
) t1
CROSS JOIN
(
SELECT c.company_name, p.latitude AS lat2, p.longitude AS lng2
FROM company c INNER JOIN postal p
ON c.postalcode = p.postalcode
) t2
HAVING distance < 20
Tim Biegeleisen 的询问启发我找到了如下可行的解决方案。
SELECT t2.company_name,
(6371 * acos(cos(radians(t1.lat1)) * cos(radians(t2.lat2))
* cos(radians(t2.lng2) - radians(t1.lng1)) + sin(radians(t1.lat1)) *
sin(radians(t2.lat2)))) AS distance,
t2.radius
FROM
(
SELECT p.latitude AS lat1, p.longitude AS lng1
FROM postal p
WHERE p.postalcode = '7894 AA'
) t1
CROSS JOIN
(
SELECT c.company_name, p.latitude AS lat2, p.longitude AS lng2,
c.radius
FROM company c
INNER JOIN postal p
ON c.postalcode = p.postalcode
) t2
HAVING distance < t2.radius
通过上述查询,距离不会与固定的公里数(例如20或50公里)进行比较,而是与每个公司的动态半径(以公里为单位)进行比较。