SQL: расчет расстояния между городом и несколькими другими местами - PullRequest
0 голосов
/ 19 октября 2019

У меня есть три таблицы в Oracle:

HOTEL: список номеров отелей, названий отелей и идентификатора города, в котором расположен отель. Здесь 5 строк (имеется в виду 5 отелей, но не в каждом городе есть отель).

ГОРОД: список идентификаторов города, названия города, долготы города и широты города. Здесь 15 строк (имеется в виду 15 городов).

ТУРИСТИЧЕСКОЕ ПРИВЛЕЧЕНИЕ: Укажите номер достопримечательности, название достопримечательности и идентификатор города, в котором находится достопримечательность. Здесь 20 рядов (имеется в виду 20 туристических достопримечательностей, в некоторых городах может быть несколько достопримечательностей, в других городах может не быть достопримечательностей).

В основном я хочу определить прямые расстояния между каждым отелем икаждая достопримечательность. Например, мне нужно расстояние между отелем 1 и аттракционом 1, затем расстояние между отелем 1 и аттракционом 2, расстояние между отелем 1 и аттракционом 3 и т. Д.

Чтобы вычислить расстояние, на котором я нахожусьиспользуя функцию геодистанции (ВЫБЕРИТЕ геодистанцию ​​(широта 1, долгота 1, широта 2, долгота 2) ОТ двойного).

Я могу получить список отелей и их соответствующих долгот и широт, присоединив ОТЕЛЬ к ГОРОДУ по ID города. Я также могу получить список туристических достопримечательностей и их соответствующие долготы и широты, присоединившись TOURIST ATTRACTION к TOWN на ID города, но в другом запросе. Когда я пытаюсь написать один запрос, я получаю сообщение об ошибке «подзапрос одной строки возвращает более одной строки».

Одним из ограничений является то, что перекрестное соединение НЕ МОЖЕТ использоваться для получения требуемых результатов. Я хочу, чтобы мои выходные данные составляли 100 строк (20 расстояний от отеля до аттракциона для каждого отеля), но я абсолютно не представляю, как это сделать без использования перекрестного соединения.

Любая помощь приветствуется.

Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 19 октября 2019

Вы, похоже, хотите вычислить cross join и расстояние:

select ha.*
from (select h.*, a.*,
             geodistance(h.latitude, h.longitude, a.latitude, a.longitude) as distance,
             row_number() over (partition by h.hotelid order by geodistance(h.latitude, h.longitude, a.latitude, a.longitude) as seqnum
      from hotel h cross join
           attraction a
     ) ha
where seqnum < 20;

Если по какой-то педантичной причине вам не разрешено cross join, один из возможных эквивалентов:

hotel h join
attraction a
on 1=1

Или в Oracle 12C:

hotel h cross apply
attraction a

Если у вас 5 отелей, 20 достопримечательностей и вы хотите 100 рядов, тогда cross join - это то, что вам нужно. Я бы сказал, что ограничение бессмысленно.

0 голосов
/ 19 октября 2019

Вам необходимо внутреннее соединение между таблицами hotel и town, которое даст вам 5 записей, а затем перекрестное соединение с таблицей tourist_attraction, которая даст 100 записей (5 * 20). Вам также понадобится снова присоединиться к этой таблице town, чтобы узнать местоположение туристического объекта.

Вы можете использовать следующий запрос:

Select h.hotel_number, 
h.hotel_name,
T.town_name,
Ta.attraction_name,
Tatown.name attraction_town_name,
geodistance(t.latitude, t.longitude, tatown.latitude, tatown.longitude) dist
From hotel h
Join town t on (h.town_id = t.town_id)
Join tourist_attraction ta on (1=1) -- way of doing cross join
Join town tatown (tatown.town_id = ta.town_id) -- used to fetch location of tourist attraction.

Пожалуйста, настройте параметры функции geodistance в соответствии стребование.

Ура !!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...