Проблема с SQLite SQL-запросом [дубликат]
Вопрос
Этот вопрос является точной копией:
Я пытаюсь выполнить следующий запрос в SQLite 3:
SELECT *,
DISTANCE(latitude, longitude, ?, ?) AS "distance"
FROM "country"
WHERE "id" NOT LIKE ?
HAVING "distance" <= ?
ORDER BY "distance" ASC;
Но я получаю следующую ошибку:
SQLSTATE[HY000]:Общая ошибка:1 Группа по пункту требуется перед
Я не понимаю, почему SQLite хочет, чтобы я группировал результаты, но я все же попробовал следующее:
SELECT *,
DISTANCE(latitude, longitude, ?, ?) AS "distance"
FROM "country"
WHERE "id" NOT LIKE ?
GROUP BY "id"
HAVING "distance" <= ?
ORDER BY "distance" ASC;
И я также попробовал это:
SELECT *,
DISTANCE(latitude, longitude, ?, ?) AS "distance"
FROM "country"
WHERE "id" NOT LIKE ?
GROUP BY "distance"
HAVING "distance" <= ?
ORDER BY "distance" ASC;
Ошибок нет, но все записи были возвращены (даже те, которые имели "distance" > ?
).Я также попробовал сделать:
SELECT *,
DISTANCE(latitude, longitude, ?, ?) AS "distance"
FROM "country"
WHERE "id" NOT LIKE ?
AND "distance" <= ?
ORDER BY "distance" ASC;
Вывод тот же, все записи были возвращены.Перепроверил - расстояние рассчитывается правильно...Я понятия не имею, что не так с этим запросом, может кто-нибудь мне помочь?
Решение
Вы не можете указать HAVING
пункт без указания GROUP BY
пункт.Использовать:
SELECT *,
DISTANCE(latitude, longitude, ?, ?) AS dist
FROM COUNTRY c
WHERE c.id NOT LIKE ?
AND DISTANCE(c.latitude, c.longitude, ?, ?) <= ?
ORDER BY dist;
Если вы не хотите вызывать DISTANCE более одного раза, вы можете использовать подзапрос:
SELECT x.*
FROM (SELECT c.*,
DISTANCE(latitude, longitude, ?, ?) AS dist
FROM COUNTRY c
WHERE c.id NOT LIKE ?) x
WHERE x.dist <= ?
ORDER BY dist;
Другие советы
Лучшим (и более быстрым) подходом может быть уменьшение количества SELECTed перед применением ORDER BY.Я использую такой подход:
ВЫБРАТЬ * ИЗ местоположений ГДЕ abs(широта - 51,123) < 0,12 AND abs(долгота - 0,123) < 0,34 ПОРЯДОК ПО РАССТОЯНИЮ (широта, долгота, 51,123, 0,123)
...где (51,123, 0,123) — это центральная точка широты/долготы, относительно которой вы ищете, а значения 0,12 и 0,34 используются для сужения поиска до квадрата на сфере по широте/долготе подходящего размера (т.квадрат размером n на n километров в этой точке земной сферы, где размер зависит от среднего географического распределения ваших местоположений).Я использую формулы градусной длины из http://en.wikipedia.org/wiki/Долгота выяснить, какие эти значения должны быть заданы с учетом положения точки поиска на сфере Земли.
это синтаксическая ошибка, вам придется использовать «группировку», когда вы используете причину,
ваш запрос с группировкой извлекает записи, имеющие («расстояние» >), потому что существует правило базы данных, согласно которому в первую очередь он берет данные с совпадающими записями, а затем выполняет группировку по ним после того, как он фильтрует записи по причине.поэтому вы никогда не получите данные, имеющие ("расстояние" <)
пожалуйста, поправьте, если я ошибаюсь
В дополнение к правильному помеченному ответу выше, если вы не хотите вызывать функцию DISTANCE дважды, обратитесь к псевдониму в предложении WHERE, т.е.:
SELECT *,
DISTANCE(latitude, longitude, ?, ?) AS dist
FROM COUNTRY c
WHERE c.id NOT LIKE ?
AND dist <= ?
ORDER BY dist;