Как создать запрос JOIN, который находит ближайший магазин для каждого пользователя - PullRequest
0 голосов
/ 10 июля 2019

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

User:
id - int
name - string
lat - decimal
long - decimal

Store:
id - int
name - string
lat - decimal
long - decimal

Я хотел бы получить запрос, который получит всех пользователей с ближайшим магазином.Меня не волнует округлость земли, потому что у каждого пользователя магазин будет довольно близко.Вот почему я решил использовать Пифагор для нахождения ближайшего расстояния:

SELECT 
   User.*, 
   Store.*, 
   Sqr((User.Lat - Store.Lat)^2+(User.Long - Store.Long)^2) AS distance
FROM User, Store

К сожалению, это дает мне декартово произведение, так что я получаю всех пользователей с расстоянием до каждого магазина.Есть ли способ получить только ближайший магазин?

Спасибо

Ответы [ 2 ]

1 голос
/ 10 июля 2019

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

Это ваш запрос с некоторыми полями, удаленными для ясности (и с псевдонимом User.Id)

SELECT 
    User.id as userid, 
    Sqr((User.Lat - Store.Lat)^2+(User.Long - Store.Long)^2) AS distance
FROM User, Store

Это оборачивает первый запрос, чтобы вычислить минимальное расстояние до магазина для каждого пользователя

select userid, min(distance) from (
    SELECT 
        User.id as userid, 
        Sqr((User.Lat - Store.Lat)^2+(User.Long - Store.Long)^2) AS distance
    FROM User, Store
 ) as x 
group by userid

Присоединитесь к исходному запросу, чтобы заполнить поля пользователя и выяснить, какое хранилище находится на этом (минимальном) расстоянии от пользователя


select z.*
from (
    select userid, min(distance) as distance from (
        SELECT 
            User.id as userid, 
            Sqr((User.Lat - Store.Lat)^2+(User.Long - Store.Long)^2) AS distance
        FROM User, Store
     ) as x 
group by userid
) as y inner join
(
    SELECT 
        User.Id as UserId, ... (populate the remaining user fields), 
        Store.*, 
        Sqr((User.Lat - Store.Lat)^2+(User.Long - Store.Long)^2) AS distance
    FROM User, Store
) as z
on y.userid = z.userid and y.distance = z.distance

0 голосов
/ 10 июля 2019

Все, что вам нужно, это перекрестное объединение таблиц и предложение WHERE, в котором вы выбираете магазин с минимальным расстоянием от каждого пользователя, например так:

select u.*, s.*
from user as u, store as s
where ((u.Lat - s.Lat)^2+(u.Long - s.Long)^2) = (
  select min((u.Lat - ss.Lat)^2+(u.Long - ss.Long)^2)
  from  store as ss
)

Вам не нужно применять Sqr()к расчетам.

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