SQL: поиск ближайшей точки в другом радиусе от заданной широты и долготы - PullRequest
0 голосов
/ 11 сентября 2018

До сих пор я был в состоянии найти ближайшую точку (склад в этом контексте) в том же радиусе. (общий вопрос с большим количеством ответов).

Это фактический код (он не использует множественный радиус)

$radius = 5; // miles

$q = "
    SELECT DISTINCT 
      warehouse_latitude.post_id,
      warehouse_longitude.meta_value as longitude,
      warehouse_latitude.meta_value as latitude,
      ((ACOS(SIN($latitude * PI() / 180) * SIN(warehouse_latitude.meta_value * PI() / 180) + COS($latitude * PI() / 180) * COS(warehouse_latitude.meta_value * PI() / 180) * COS(($longitude - warehouse_longitude.meta_value) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) AS distance
    FROM {$this->wpdb->postmeta} as warehouse_latitude
      LEFT JOIN {$this->wpdb->postmeta} as warehouse_longitude ON warehouse_latitude.post_id = warehouse_longitude.post_id 
    WHERE warehouse_latitude.meta_key = 'warehouse_latitude' AND warehouse_longitude.meta_key = 'warehouse_longitude'
    HAVING distance < $radius
    ORDER BY distance ASC
    LIMIT 1
";

Вместо:

Я бы хотел выбрать ближайшую точку, но для каждой точки определен радиус (склад).

  • Точка A (9714): радиус 5 миль
  • Точка B (9715): радиус 2 мили
  • Точка C (9716): радиус 10 миль

Таким образом, если точки B и C находятся в диапазоне, а точка B является ближайшей, следует выбрать точку B.

Таблица wp_postmeta:

meta_id | post_id | meta_key             | meta_value
------------------------------------------------------
324802  | 9714    | warehouse_latitude   | 47.1978754
324809  | 9715    | warehouse_latitude   | 47.2064462
324814  | 9716    | warehouse_latitude   | 47.214434
324803  | 9714    | warehouse_longitude  | -1.54441
324810  | 9715    | warehouse_longitude  | -1.5461347
324815  | 9716    | warehouse_longitude  | -1.565993
324806  | 9714    | warehouse_radius     | 5
324811  | 9715    | warehouse_radius     | 2
324816  | 9716    | warehouse_radius     | 10

Схема:

enter image description here

Ответы [ 2 ]

0 голосов
/ 11 сентября 2018

Не ответ.Слишком долго для комментария ...

1  LEFT JOIN warehouse_longitude ON ... -- This is an INNER JOIN because of LINE 3
2  LEFT JOIN warehouse_radius ON ...    -- This is also an INNER JOIN, because of LINE 4 
3 WHERE warehouse_longitude.meta_key = 'warehouse_longitude' 
4   AND warehouse_radius.meta_key = 'warehouse_radius'

Так что вы могли бы также написать их как ВНУТРЕННИЕ СОЕДИНЕНИЯ для начала.

0 голосов
/ 11 сентября 2018

Итак, вот решение (обновлено из предыдущего запроса).

Не против дать еще один ответ, если у вас есть более эффективный / читаемый способ вычисления расстояния.

SELECT DISTINCT 
  warehouse_latitude.post_id,
  warehouse_longitude.meta_value as longitude,
  warehouse_latitude.meta_value as latitude,
  warehouse_radius.meta_value as radius,
  ((ACOS(SIN($latitude * PI() / 180) * SIN(warehouse_latitude.meta_value * PI() / 180) + COS($latitude * PI() / 180) * COS(warehouse_latitude.meta_value * PI() / 180) * COS(($longitude - warehouse_longitude.meta_value) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) AS distance
FROM {$this->wpdb->postmeta} as warehouse_latitude
  LEFT JOIN {$this->wpdb->postmeta} as warehouse_longitude ON warehouse_latitude.post_id = warehouse_longitude.post_id
  LEFT JOIN {$this->wpdb->postmeta} as warehouse_radius ON warehouse_latitude.post_id = warehouse_radius.post_id 
WHERE warehouse_latitude.meta_key = 'warehouse_latitude' AND warehouse_longitude.meta_key = 'warehouse_longitude' AND warehouse_radius.meta_key = 'warehouse_radius'
HAVING distance < (radius * 0.62)
ORDER BY distance ASC
LIMIT 1

Я добавил соединение для значений радиуса:

LEFT JOIN {$this->wpdb->postmeta} as warehouse_radius ON warehouse_latitude.post_id = warehouse_radius.post_id 

И еще одно условие в инструкции WHERE:

AND warehouse_radius.meta_key = 'warehouse_radius'

Следовательно:

Я могу обновить инструкцию HAVING до:

HAVING distance < (radius * 0.62) -- Km to Miles
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...