Problèmes avec SQLite SQL Query [double]
Question
Cette question est une copie exacte:
- SQLite - clause WHERE & UDFs 4 réponses
Je suis en train d'exécuter la requête suivante dans SQLite 3:
SELECT *,
DISTANCE(latitude, longitude, ?, ?) AS "distance"
FROM "country"
WHERE "id" NOT LIKE ?
HAVING "distance" <= ?
ORDER BY "distance" ASC;
Mais je reçois l'erreur suivante:
SQLSTATE [HY000]: Erreur générale: 1 a Clause GROUP BY est nécessaire avant AYANT
Je ne comprends pas pourquoi SQLite veut que les résultats du groupe, mais j'essayé ce qui suit:
SELECT *,
DISTANCE(latitude, longitude, ?, ?) AS "distance"
FROM "country"
WHERE "id" NOT LIKE ?
GROUP BY "id"
HAVING "distance" <= ?
ORDER BY "distance" ASC;
Et j'ai aussi essayé ceci:
SELECT *,
DISTANCE(latitude, longitude, ?, ?) AS "distance"
FROM "country"
WHERE "id" NOT LIKE ?
GROUP BY "distance"
HAVING "distance" <= ?
ORDER BY "distance" ASC;
Pas d'erreur, mais tous les dossiers ont été retournés (même ceux ayant "distance" > ?
). J'ai aussi essayé de le faire:
SELECT *,
DISTANCE(latitude, longitude, ?, ?) AS "distance"
FROM "country"
WHERE "id" NOT LIKE ?
AND "distance" <= ?
ORDER BY "distance" ASC;
Même sortie, tous les dossiers ont été retournés. Je l'ai vérifié deux fois - la distance est calculée correctement ... Je ne sais pas quel est le problème avec cette requête, quelqu'un peut me aider
La solution
Vous ne pouvez pas spécifier une clause de HAVING
sans avoir spécifié une clause de GROUP BY
. Utilisation:
SELECT *,
DISTANCE(latitude, longitude, ?, ?) AS dist
FROM COUNTRY c
WHERE c.id NOT LIKE ?
AND DISTANCE(c.latitude, c.longitude, ?, ?) <= ?
ORDER BY dist;
Si vous ne voulez pas appeler DISTANCE plus d'une fois, vous pouvez utiliser une sous-requête:
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;
Autres conseils
Une meilleure (et plus rapide) approche pourrait consister à réduire sur le régler avant d'appliquer SELECTIONNES ORDER BY. J'utilise ce type d'approche:
SELECT * FROM endroits où abs (Latitude - 51,123) <0,12 ET abs (Longitude - 0,123) <0,34 ORDER BY DISTANCE (latitude, longitude, 51,123, 0,123)
... où (51,123, 0,123) est le point de latitude centre / longitude vous recherchez par rapport à, et les valeurs de 0,12 et 0,34 sont utilisés pour affiner votre recherche à un lat / long carré sur un -sphere d'une taille appropriée (soit un carré de kilomètres de n par n kilomètres à ce point sur la sphère de la Terre, où la taille dépend de la répartition géographique moyenne de vos sites). J'utilise les formules de longueur de degré de http://en.wikipedia.org/wiki/Longitude de comprendre ce que ces valeurs devraient donner la position du point de recherche sur la sphère de la Terre.
il est erreur de syntaxe, vous devez utiliser « groupe par » lorsque vous utilisez la cause ayant,
votre requête avec le groupe par est aller chercher des documents ayant ( « distance »>) car il est la règle de base de données qu'il faut d'abord toutes les données avec les enregistrements correspondants il interprétera groupe par là-dessus après qu'il est le filtrage des enregistrements en ayant cause. de sorte que vous ne recevez jamais les données ayant ( "distance" <)
S'il vous plaît corriger si je me trompe
Suite à la bonne réponse ci-dessus battant pavillon, si vous ne voulez pas appeler la fonction DISTANCE deux fois, reportez-vous à l'alias dans la clause WHERE, i.e.:
SELECT *,
DISTANCE(latitude, longitude, ?, ?) AS dist
FROM COUNTRY c
WHERE c.id NOT LIKE ?
AND dist <= ?
ORDER BY dist;