Intereting Posts
Выбор всех людей с максимальным возрастом? Ищете номер телефона, содержащий минус, например «123-456789», создание временной таблицы из запроса с использованием sqlalchemy orm Тип данных временной метки Oracle Создайте поля даты в день, месяц, год в MySQL Наибольшая N на группу проблем Sql в mysql Создание двух столбцов из строк таблицы Список всех родительских элементов в таблице иерархии как строка с разделителями SQL Группа MySQL по интервалам в диапазоне дат Установите пустые строки ('') в NULL во всей базе данных Как получить имя базы данных из строки подключения с помощью SqlConnectionStringBuilder список, разделенный запятыми, в результате выражения select в Oracle Создание отчета по URL-адресу – SQL Server Reporting Services 2008 Неожиданные запросы SQL к базе данных Postgres на Rails / Heroku Как сопоставить значения двух столбцов (одной таблицы) по диагонали и отображать результат, когда они не совпадают

Вложенные SQL-запросы Rails

У меня есть модель базы данных Position(lat,lon) которая содержит latitudes и longitudes.

У меня есть действие контроллера, называемое show_close_by которое получает позицию в градусах (my_lat, my_lon) , допуск (в километрах) и должен возвращать список позиций в базе данных, находящихся в пределах допустимого диапазона.

Для этого я использую формулу haversine_distance, которая вычисляет расстояние в километрах (на поверхности Земли) между двумя координатами (lat1, lon1, lat2, lon2) .

Чтобы сделать запрос быстрее, я написал всю формулу haversine_distance в запросе:

 ... WHERE 2*6371*asin(sqrt( power( sin( (:lat2-latitude)*pi()/(180*2) ) ,2) + cos(latitude*pi()/180)*cos(:lat2*pi()/180)*power(sin( (:lon2-longitude)*pi()/(180*2) ),2) )) < tolerance 

Специфика запроса не имеет значения. Я сомневаюсь: необходимо ли вычислить эту огромную функцию для КАЖДОЙ позиции в базе данных? Могу ли я отфильтровать некоторые позиции, которые явно слишком далеки, с более простой функцией?

Ну, я могу: с вложенным SQL-запросом я могу запросить базу данных для позиций, которые находятся в большом «квадрате» (в пространстве lat / lon), а затем отфильтровывать те, у которых более затратная тригонометрическая функция. Что-то вроде следующего:

 SELECT * FROM ( SELECT * FROM Positions WHERE lat-latitude < some_reasonable_upper_bound AND lon-longitude < same_upper_bound ) WHERE costly_haversine_distance < tolerance 

Наконец, мой вопрос: как я могу реализовать это в Rails (без написания всего запроса сам)? Does Positions.where(reasonable_upper_bound).where(costly_but_accurate_restriction) делает вложенный запрос? Если нет, то как?

Большое спасибо!

Вот как сделать вложенные запросы:

 LineItem.where(product_id: Product.where(price: 50)) 

Он делает следующий запрос:

 SELECT "line_items".* FROM "line_items" WHERE "line_items"."product_id" IN (SELECT "products"."id" FROM "products" WHERE "products"."price" = 50) 

Обратите внимание, что из таблицы products будут извлекаться только id s. Если вы пытаетесь сделать другой способ подключения двух объектов, и эта магия не подходит, используйте Product.select(:some_field).where(...) .