I) ПРОБЛЕМА
Допустим, есть 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
III) ТЕКУЩИЙ РЕЗУЛЬТАТ
| 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
Iнеобходимо рассчитать расстояние между всеми местами назначения и всеми агентскими (личными) местами, а затем выбрать кратчайшее (минимальное) расстояние.
V) ВОПРОС (S)
Как получить ожидаемый результат?Я полагаю, что не так сложно выбрать минимальное расстояние с помощью MIN ()?Но как мне пройти каждый ряд агентских (личных) мест?Нужно ли использовать цикл (курсор? Могу ли я использовать его здесь?) Или есть другой (более простой) способ сделать это?
Большое спасибо за любой совет!
СМОТРИ ДЕМО ЗДЕСЬ