Это просто выходит за рамки моих возможностей в SQL. У меня есть запрос, который выбирает все объекты с определенным радиусом объекта, который отлично работает. Сначала он создает ограничительную рамку для получения всех потенциальных кандидатов, а затем вычисляет радиус из этого ограничивающего прямоугольника для выбора результатов.Оптимизировать сложное выражение SQL
SELECT *
FROM (
SELECT b.*, pr.postcode, pr.prize, pr.title, pr.collection, pr.redeemed, pr.delivery, pr.archived, bt.category, b.id as objectid, b.updated as changed,
p.radius,
p.distance_unit
* DEGREES(ACOS(COS(RADIANS(p.latpoint))
* COS(RADIANS(b.lat))
* COS(RADIANS(p.longpoint - b.lng))
+ SIN(RADIANS(p.latpoint))
* SIN(RADIANS(b.lat))))
AS distance
FROM bubbles AS b, bubble_prizes AS pr, bubble_types AS bt
JOIN (
SELECT ? AS latpoint, ? AS longpoint,
? AS radius, ? AS distance_unit
) AS p
WHERE pr.bubble = b.id
AND b.deleted = 0
AND b.type IN ($placeholders)
AND b.type = bt.type
AND b.updated > $since
AND b.lat
BETWEEN p.latpoint - (p.radius/p.distance_unit)
AND p.latpoint + (p.radius/p.distance_unit)
AND b.lng
BETWEEN p.longpoint - (p.radius/(p.distance_unit * COS(RADIANS(p.latpoint))))
AND p.longpoint + (p.radius/(p.distance_unit * COS(RADIANS(p.latpoint))))
) AS d
WHERE distance <= radius
ORDER BY distance";
(Этот запрос был получен из этой статьи http://www.movable-type.co.uk/scripts/latlong-db.html)
Моя проблема заключается в том, что теперь я хотел бы изменить это так, что он выбирает все объекты, где
b.created = идентификатор пользователя или б .catch_held = userid ИЛИ [объекты находятся в пределах определенного радиуса точки (как указано выше)]
Он также должен быть эффективным. То есть, в случае, когда b.created = userid ИЛИ b.catch_held = userid, я не хочу вычислять DISTANCE или делать какие-либо вычисления с ограничительной рамкой, и я не уверен, как реструктурировать запрос для достижения этого.
Обратите внимание, что никакие условия, связанные с расстоянием, не должны оставаться на месте независимо от create или catct_held. То есть
pr.bubble = b.id
AND b.deleted = 0
AND b.type IN ($placeholders)
AND b.type = bt.type
AND b.updated > $since
Может кто-то помочь в этом?
Спасибо за вход Гордон. Это страдает той же проблемой, что и у меня с различными вещами, которые я пробовал, а это значит, что b, похоже, не существует, и вы получаете: Неизвестный столбец «b.creator» в разделе «where». Если я удаляю операторы OR, прошедшие расстояние <= radius, он анализирует, но не работает. – mark
Извините, я имею в виду b.created not b.creator в ошибке выше ... – mark
@mark. , , Алиасом внешнего запроса является 'd' not' b', поэтому его следует использовать для внешней ссылки. –