MySQL запрос с группировкой, процедурой и "HAVING"
В настоящее время у меня есть этот запрос:
SELECT *, GEODIST(41.3919671, 2.1757278, latitude, longitude) distance
FROM offers_all
WHERE id_family=1761 AND GEODIST(41.3919671, 2.1757278, latitude, longitude) <= 40
GROUP BY id_prod ORDER BY pricepromo ASC
Как видите, он использует процедуру MySQL, называемую GEODIST (формула Хаверсайна, возвращает расстояние в КМ между координатами) и группирует результаты по id_prod
,
Таблица может содержать более одного предложения на один продукт (id_prod
). Цель состоит в том, чтобы получить список предложений без повторяющихся продуктов, поэтому вернуть лучший (самый дешевый, самый близкий) случай для этого предложения.
Предыдущий запрос, кажется, хорошо справляется со своей задачей, но для дальнейшей оптимизации я хотел бы использовать HAVING
(не нужно запускать Haversine дважды для каждого ряда). Это была моя первая мысль:
SELECT *, MIN(GEODIST(41.3919671, 2.1757278, latitude, longitude)) distance
FROM offers_all
WHERE id_family=1761
GROUP BY id_prod
HAVING distance <= 40
ORDER BY pricepromo ASC
К сожалению, этот запрос не возвращает те же результаты, что и ранее.
Без использования MIN()
, результаты были неверными (возвращает только одну строку). С помощью MIN()
(как и в последнем запросе), информация о строке неверна (т.е. не возвращает ожидаемую строку, что приводит к результатам, показывающим в списке неправильное название магазина и цену).
Любые советы или ответы о лучшем запросе для этой цели (и другие предложения) приветствуются:D
2 ответа
Вы можете сделать это с помощью производной таблицы:
SELECT t.*, MIN(t.distance) AS distance
FROM (SELECT *, GEODIST(41.3919671, 2.1757278, latitude, longitude) AS distance
FROM offers_all
WHERE id_family=1761) AS t
WHERE t.distance <= 40
GROUP BY t.id_prod
ORDER BY t.pricepromo ASC
Я почти уверен, что некоторые люди предложат подход "тот же самый стол-псевдоним-соединение", поэтому я предприму попытку "других предложений":
Вы уже используете Sphinx в этом проекте, возможно, для полнотекстового поиска продукта? Sphinx может предоставить вам встроенную поддержку геодистанций, просто несколько случайных URL, которые я получил в прошлом по этой теме:
http://www.fliquidstudios.com/2011/06/17/an-introduction-to-distance-based-searching-in-sphinx/
http://www.sanisoft.com/blog/2011/05/02/geo-distance-search-in-sphinx/
Больше по теме на самом форуме Sphinx:
http://sphinxsearch.com/forum/view.html?id=7276
Кроме того, возможно, вы бы предпочли использовать подход "Tiles" для исполнения:
http://sphinxsearch.com/forum/view.html?id=7823