#sql #sql-server #tsql #inner-join #spatial
#sql #sql-server #tsql #внутреннее соединение #пространственный
Вопрос:
У меня есть таблица сопоставления LocationID вместе с их значением широты и долготы центра, как показано ниже-
| Location Id | Center_lat | Center_long |
|-------------|------------|-------------|
| 1 | 50.546 | 88.344 |
| 2 | 48.546 | 86.344 |
| 3 | 52.546 | 89.344 |
У меня есть другая таблица, в которой я получаю непрерывные данные о местоположении с широтой и долготой для пользователя, как показано ниже —
--------- ------------ -------------
| User Id | Center_lat | Center_long |
--------- ------------ -------------
| 101 | 50.446 | 88.314 |
| 102 | 48.446 | 86.314 |
| 103 | 52.446 | 89.314 |
--------- ------------ -------------
Я хочу получить LocationID всех пользователей, если их значения широты и долготы находятся в пределах 1000 метров от значений длины широты, соответствующих идентификатору местоположения. Как я могу это сделать в T-SQL?
Итоговая таблица должна выглядеть следующим образом —
--------- ------------ ------------- ------------
| User Id | Center_lat | Center_long | LocationId |
--------- ------------ ------------- ------------
| 101 | 50.546 | 88.344 | 1 |
| 102 | 48.546 | 86.344 | 2 |
| 103 | 52.546 | 89.344 | 3 |
--------- ------------ ------------- ------------
Комментарии:
1. Есть ли причина, по которой вы не используете
geography
тип, а не сохраняете lat / long в отдельных столбцах?
Ответ №1:
Вы можете использовать преобразование пар широта / долгота в geography
объекты, а затем использовать stdistance()
:
select u.*, l.location_id
from users u
inner join locations l
on geography::point(u.center_lat, u.center_long, 4326).stdistance(geography::point(l.center_lat, l.center_long, 4326)) < 1000
Обратите внимание, что было бы гораздо эффективнее хранить эту информацию как point
s для начала.