mysql - 使用 MySQL 空间计算许多点之间的最短距离(通过循环中的行?)
问题描述
一)问题
假设有 4 个表:
表:assignment_has_place
| assignment_id | place_id |
|---------------|----------|
| 1 | 1 |
| 2 | 4 |
| 2 | 5 |
表:agent_has_place
| agent_id | place_id |
|----------|----------|
| 1 | 2 |
| 2 | 1 |
| 1 | 3 |
| 1 | 4 |
| 3 | 4 |
| 3 | 6 |
表:assignment_has_agent
| assignment_id | agent_id |
|---------------|----------|
| 1 | 1 |
| 1 | 2 |
| 2 | 3 |
表:地点(测试数据)
| Place_id | Name | Geodata |
|----------|-------------|-------------------------|
| 1 | New-York | POINT(-74.0072 40.7131) |
| 2 | Los Angeles | POINT(-118.244 34.0522) |
| 3 | Boston | POINT(-71.0589 42.3601) |
| 4 | Chicago | POINT(-87.6298 41.8781) |
| 5 | Dallas | POINT(-96.797 32.7767) |
| 6 | Austin | POINT(-97.7431 30.2672) |
所以,一个任务可以有很多地方,一个代理可以有很多(个人)地方(例如家庭、工作、父母家等),一个任务可以有很多代理人。
我研究了代理人分配地点和代理人(个人)地点之间的关系。然后,我想知道每个代理分配地点和他所有(个人)地点之间的最短距离。(换句话说,我想为他的每个分配地点找到最近的代理人(个人)地点,并知道他们之间的距离)。
II) 当前查询
SELECT
assignment_has_agent.agent_id AS agent,
place.place_id AS place_of_assignment,
-- BEGIN. Calculate distance between agents places and agents places of assignment
ST_Distance_Sphere(place.geodata, -- This is a geodata about a place of assignment
-- BEGIN. Select geodata for all agents places
(SELECT
place.geodata -- This is a geodata about an agents place
FROM
place
INNER JOIN agent_has_place -- Get geodata about agents place
ON agent_has_place.place_id = place.place_id
WHERE agent_has_place.agent_id = assignment_has_agent.agent_id
LIMIT 1 -- Here the problem!!! Without LIMIT Mysql error "Subquery returns more than 1 row"
)
-- END. Select geodata for all agents places
)
AS shortest_distance
-- END. Calculate distance between agents places and agents places of assignment
FROM
assignment_has_place
LEFT JOIN assignment_has_agent -- Make a link between assignment and agent
ON assignment_has_agent.assignment_id = assignment_has_place.assignment_id
LEFT JOIN place -- Get a geodata about the place of assignment
ON place.place_id = assignment_has_place.place_id
GROUP BY assignment_has_agent.agent_id, place.place_id
三)目前的结果
| agent | place_of_assignment | shortest_distance |
|-------|---------------------|--------------------|
| 1 | 1 | 3935659.762302256 | -- Note: New-York<>Los Angeles
| 2 | 1 | 0 | -- Note: New-York<>New-York
| 3 | 4 | 0 | -- Note: Chicago<>Chicago
| 3 | 5 | 1294952.4320354236 | -- Note: Dallas<>Chicago
在我当前的查询中,我必须添加LIMIT 1,否则我有 mysql 错误“子查询返回超过 1 行”。(见上面的代码。)这是因为代理可以有很多(个人)的地方。所以这个结果是不正确的,因为它只占所有代理(个人)位置中的第一行。
IV) 预期结果
| agent | place_of_assignment | shortest_distance |
|-------|---------------------|--------------------|
| 1 | 1 | 306167.42792567355 | -- Note: New-York<>Boston
| 2 | 1 | 0 | -- Note: New-York<>New-York
| 3 | 4 | 0 | -- Note: Chicago<>Chicago
| 3 | 5 | 293094.4286555507 | -- Note: Dallas<>Austin
我需要计算所有分配地点和所有代理(个人)地点之间的距离,然后选择最短(最小)距离。
五)问题(S)
如何获得预期的结果?我想用 MIN() 选择最短距离并不太难?但是我如何才能处理每一行代理(个人)位置?我是否必须使用循环(光标???我可以在这里使用它吗?)还是有任何其他(更简单)的方法可以做到这一点?
非常感谢您的任何建议!
在此处查看演示
解决方案
推荐阅读
- typescript - 获取对象键类型的打字稿
- android - CSS Id 选择器阻止所有内容在 Android 10 上的 Xamarin.Forms WebView 中显示
- r - 有没有办法在 ggplot 中为每个图获得不同颜色轴的多面板图?
- javascript - setState 在开发过程中按预期工作,在部署时变慢
- microsoft-teams - 尝试为 Teams 安装新的机器人应用程序会产生一般错误“清单解析失败”
- sql - NetSuite 已保存搜索:尝试显示最近的最近拣货标记,其值为 true
- java - 无法在 Java 6 上运行 Java Spring 应用程序。说它需要 JDK 1.5 或更高版本
- r - “错误:参数 1 必须是数据帧或命名原子向量。” for `purrr::map_dfr()`
- javascript - 加载图片后使用JS更改图片元素的来源?
- r - 根据 R 中列的 2 次或多次出现过滤行