Pergunta

Esta pergunta é uma duplicata exata de:

Estou tentando executar a seguinte consulta no SQLite 3:

SELECT *,
  DISTANCE(latitude, longitude, ?, ?) AS "distance"
FROM "country"
WHERE "id" NOT LIKE ?
HAVING "distance" <= ?
ORDER BY "distance" ASC;

Mas recebo o seguinte erro:

SQLSTATE[HY000]:Erro geral:1 Um grupo por cláusula é necessário antes de ter

Não entendo por que o SQLite quer que eu agrupe os resultados, mas ainda tentei o seguinte:

SELECT *,
  DISTANCE(latitude, longitude, ?, ?) AS "distance"
FROM "country"
WHERE "id" NOT LIKE ?
GROUP BY "id"
HAVING "distance" <= ?
ORDER BY "distance" ASC;

E eu também tentei isso:

SELECT *,
  DISTANCE(latitude, longitude, ?, ?) AS "distance"
FROM "country"
WHERE "id" NOT LIKE ?
GROUP BY "distance"
HAVING "distance" <= ?
ORDER BY "distance" ASC;

Não houve erros, mas todos os registros foram retornados (mesmo aqueles com "distance" > ?).Eu também tentei fazer:

SELECT *,
  DISTANCE(latitude, longitude, ?, ?) AS "distance"
FROM "country"
WHERE "id" NOT LIKE ?
  AND "distance" <= ?
ORDER BY "distance" ASC;

Mesma saída, todos os registros foram retornados.Verifiquei novamente - a distância está sendo calculada corretamente...Não tenho ideia do que há de errado com esta consulta, alguém pode me ajudar?

Foi útil?

Solução

Você não pode especificar um HAVING cláusula sem ter especificado um GROUP BY cláusula. Usar:

  SELECT *, 
         DISTANCE(latitude, longitude, ?, ?) AS dist
    FROM COUNTRY c
   WHERE c.id NOT LIKE ?
     AND DISTANCE(c.latitude, c.longitude, ?, ?) <= ?
ORDER BY dist;

Se você não quiser ligar para a distância mais de uma vez, pode usar uma subconeração:

  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;

Outras dicas

Uma abordagem melhor (e mais rápida) seria reduzir o conjunto SELECTed antes de aplicar ORDER BY.Eu uso esse tipo de abordagem:

SELECIONE * FROM Locais ONDE abs(Latitude - 51,123) <0,12 AND abs(Longitude - 0,123) <0,34 ORDEM POR DISTÂNCIA(Latitude, Longitude, 51,123, 0,123)

... onde (51,123, 0,123) é o ponto central de latitude/longitude ao qual você está pesquisando, e os valores de 0,12 e 0,34 são usados ​​para restringir sua pesquisa a um quadrado lat/long em uma esfera de um tamanho apropriado (ou seja,um quadrado de n quilômetros por n quilômetros naquele ponto da esfera da Terra, onde o tamanho depende da distribuição geográfica média de suas localizações).Eu uso as fórmulas de comprimento de grau de http://en.wikipedia.org/wiki/Longitude para descobrir quais devem ser esses valores dada a posição do ponto de pesquisa na esfera da Terra.

É um erro de sintaxe, você deve usar 'grupo por' quando estiver usando a causa,

Sua consulta com o grupo por está buscando registros com ("distância">) porque, existe uma regra de banco de dados que, antes de tudo, leva dados com registros correspondentes, então ele executará o grupo por ele depois que ele está filtrando registros por causa. Então você nunca obtém dados tendo ("distância" <)

Por favor, corrija se eu estiver errado

Além da resposta sinalizada correta acima, se você não quiser chamar a função de distância duas vezes, consulte o alias na cláusula onde, ou seja::

 SELECT *, 
         DISTANCE(latitude, longitude, ?, ?) AS dist
    FROM COUNTRY c
   WHERE c.id NOT LIKE ?
     AND dist <= ?
ORDER BY dist;
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top