Вопрос

Этот вопрос является точной копией:

Я пытаюсь выполнить следующий запрос в 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;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top