Вложенное заявление MySQL для географических координат - PullRequest
0 голосов
/ 29 июня 2011

Не уверен, что это логический вопрос или вопрос MySQL ... но мне все равно нужна помощь.

У меня есть список регионов с координатами в каждом.Размер базы данных составляет около 115 МБ.Вот выборка записей:

|  PC1  |  PC2  |   CITY    | PROV  | AREACODE  |    LAT      |     LNG      | 
|  A1A  |  0B8  | ST. JOHNS |  NL   |    709    |47.5986880000|-52.7255210000|
|  A1A  |  0B9  | ST. JOHNS |  NL   |    709    |47.5505750000|-52.7460720000|

И так далее, и так далее ...

Что мне нужно сделать, это получить запись в каждом городе, которая представляет максимальную широту и значение долготы, затем максимальная широта и минимальное значение долготы, затем запись с минимальным широтным значением и минимальное продольное значение, затем запись с минимальным широтнымзначение и максимальное продольное значение.

То, с чего я начал, было:

SELECT MAX(lat), MAX(lng), MIN(lat), MIN(lng), city FROM places GROUP BY city

Это дало мне ОДНУ запись на город, со значениями MAX / MIN, которые я запрашивал, но эти min и max представляли отдельные запросы дляминимальная широта, максимальная широта и т. д., что дало мне довольно хорошую оценку площади, чтобы я мог нарисовать многоугольник над картой Google ... но это квадраты, и есть много совпадений, и я знаю, что могу сделатьэто лучше ... эти результаты представляют МАКСИМАЛЬНЫЙ север, юг, восток, запад ЛЮБОЙ записи в группе записей города ..

Что я хочу сделать, так это поиск ОДНОЙ записи, которая имеет максимальную широтуи максимальное продольное значение, затем максимальное широтное и минимальное продольное значение, и т. д.

Не уверен, как вложить эти операторы SQL ... Я пробовал несколько операторов IN, но всегда приводил к одной записикоторый не совсем соответствует максимальным или минимальным значениям.

Ответы [ 2 ]

0 голосов
/ 30 июня 2011

Что я хочу сделать, так это поиск ОДНОЙ записи, которая имеет максимальное широтное и максимальное продольное значение

Но почти наверняка не будет ОДНОЙ записи, которая имеет максимальный лат и максимальный длинный. Каков ваш желаемый результат, когда одно место находится дальше на север, а другое - дальше на восток?

Вы ищете «самое северо-восточное» место в городе? В каком случае:

SELECT * FROM places WHERE city='ST. JOHNS'
ORDER BY MAX(lat+lng) DESC LIMIT 1;

и аналогично MIN и / или lat-lng для других диагональных направлений.

Чтобы получить максимальную северо-восточную часть для каждого города, у вас есть проблема «максимум на группу», которая является распространенной проблемой SQL. Смотрите, например, этот вопрос для обсуждения. Пример наиболее северо-восточного места на город:

SELECT p0.*
FROM places AS p0
LEFT JOIN places AS p1 ON p1.city=p0.city AND p1.lat+p1.lng>p0.lat+p0.lng
WHERE p1.city IS NULL

Однако эти запросы вычисляемого порядка являются неиндексируемыми, поэтому, вероятно, неэффективными, если вы фактически не добавите индексированный столбец для lat + lng.

Тогда у вас есть проблема с попыткой подогнать все четыре запроса (версии NE, SE, SW и NW) к одному и тому же запросу. Лучшим способом решения этой проблемы обычно не является: Выполнить четыре отдельных запроса. Как правило, различные сокращения, которые вы пытаетесь втиснуть четырьмя отдельными операциями в один запрос, оставляют вас с чем-то менее эффективным и гораздо менее читаемым, чем четыре отдельных запроса.

В любом случае, я действительно не вижу, куда вас это приведет. Если вы пытаетесь нарисовать минимальный непрямоугольный многоугольник вокруг набора точек на карте, вам нужно будет выбрать каждую точку для города и использовать алгоритм выпуклой оболочки или какое-либо дерево квадрантов. Слишком вовлечен, чтобы делать в SQL.

0 голосов
/ 29 июня 2011

Не уверен, правильно ли я понял ваш вопрос, но вы можете посмотреть на предложение HAVING

SELECT lat, lng, city FROM places GROUP BY city HAVING lat=MAX(lat)

или СОЮЗ

(SELECT MAX(lat), MAX(lng), city FROM places GROUP BY city)
 UNION
(SELECT MAX(lat), MIN(lng), city FROM places GROUP BY city)

или смесь двух

(SELECT MAX(lat), MAX(lng), city FROM places GROUP BY city HAVING lat=MAX(lat))
 UNION
(SELECT MAX(lat), MIN(lng), city FROM places GROUP BY city HAVING lng=MIN(lng))
...