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

Était-ce utile?

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;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top