Je n'ai pas le temps en ce moment pour élaborer une requête correcte, mais Je vais montrer ce qui ne va pas avec la requête existante à première vue.
1) En ce qui concerne votre question actuelle: Le message d'erreur indique ERROR 1248 (42000): Every derived table must have its own alias
et indique déjà ce qui ne va pas. La sous-requête dans la partie suivante
LEFT JOIN (select s.zip,
s.username,
m.longitude,
m.latitude,
m.zip
from users s) on u.zip = s.zip
a besoin de son propre alias, ce qui devrait éventuellement
LEFT JOIN (select s.zip,
s.username,
m.longitude,
m.latitude,
m.zip
from users s) t on u.zip = t.zip
(notez le T après la parenthèse fermante et le remplacement de s.zip par t.zip) . Mais même si vous faites cela, vous rencontrerez le problème 2 (voir la section suivante).
2) La sous-requête
(select s.zip,
s.username,
m.longitude,
m.latitude,
m.zip
from users s)
jetteront une autre erreur car la table m ne sait pas dans ce sous-requête.
Si vous parvenez à le résoudre correctement, je vous suggère de modifier votre question et de nous en faire part. Si ce n'est pas le cas, postez un commentaire ou modifiez votre question en décrivant les autres problèmes que vous rencontrez.
EDIT
J'ai maintenant élaboré une solution pour vous:
SELECT zipcodes.zip,
(3959 * acos(cos(radians(zipcodes.latitude)) *
cos(radians(center.latitude)) *
cos(radians(zipcodes.longitude) -
radians(center.longitude)) +
sin(radians(zipcodes.latitude)) *
sin(radians(center.latitude)))) AS distance FROM
(SELECT users.username,
users.zip,
zipcodes.latitude,
zipcodes.longitude FROM
(users JOIN zipcodes ON users.zip = zipcodes.zip)
WHERE (username='Tester1')
) center, zipcodes
HAVING (distance < 5000)
ORDER BY distance;
Ce sélectionne tous les codes postaux qui sont à la distance désirée, classés par ordre de distance.
Comme vous pouvez le remarquer, j'ai simplifié le code. S'il vous plaît noter également que j'ai testé cela en fonction de vos anciennes données (les données que vous avez montré avant votre modification), mais en utilisant Tester1
au lieu de tester55
.
Vous avez en effet besoin de HAVING
au lieu de WHERE
lors du filtrage, donc ma déclaration initiale à ce sujet était trompeuse.La raison en est que MySQL n'autorise pas les colonnes calculées (dans ce cas: distance) dans les clauses WHERE
, mais dans les clauses HAVING
. C'est un comportement non-standard; Habituellement, vous devez résoudre ce problème d'une autre manière. Je ne vais pas m'étendre là-dessus parce que c'est une autre question potentiellement inquiétante qui n'est pas étroitement liée à votre question initiale.
EDIT 2
Enfin, voici la version qui donne le nom d'utilisateur en plus:
SELECT zipcodes.zip,
users.username,
(3959 * acos(cos(radians(zipcodes.latitude)) *
cos(radians(center.latitude)) *
cos(radians(zipcodes.longitude) -
radians(center.longitude)) +
sin(radians(zipcodes.latitude)) *
sin(radians(center.latitude)))) AS distance FROM
((SELECT users.username,
users.zip,
zipcodes.latitude,
zipcodes.longitude FROM
(users JOIN zipcodes ON users.zip = zipcodes.zip)
WHERE (username='Tester1')
) center, zipcodes) INNER JOIN users ON zipcodes.zip = users.zip
WHERE (users.username <> 'Tester1')
HAVING (distance < 5000)
ORDER BY distance;
S'il vous plaît noter que vous devez le troisième de la dernière ligne pour filtrer l'utilisateur que vous calculez les distances pour. Si vous ne faites pas cela, le résultat inclura une ligne avec l'utilisateur lui-même (dans ce cas: Tester1
) et une distance de (presque) 0
.
EDIT 3
Ce qui suit est une version telle que demandée par les commentaires ci-dessous (rayon recherche souhaité stocké sous forme de champ seekingdistance
supplémentaire dans le tableau users
):
SELECT zipcodes.zip,
users.username,
center.seekingdistance,
(3959 * acos(cos(radians(zipcodes.latitude)) *
cos(radians(center.latitude)) *
cos(radians(zipcodes.longitude) -
radians(center.longitude)) +
sin(radians(zipcodes.latitude)) *
sin(radians(center.latitude)))) AS distance FROM
((SELECT users.username,
users.zip,
users.seekingdistance,
zipcodes.latitude,
zipcodes.longitude FROM
(users JOIN zipcodes ON users.zip = zipcodes.zip)
WHERE (username='Tester1')
) center, zipcodes) INNER JOIN users ON zipcodes.zip = users.zip
WHERE (users.username <> 'Tester1')
HAVING (distance < center.seekingdistance)
ORDER BY distance;
En ce qui concerne votre édition: Peut-être que vous êtes penser trop compliqué. Par exemple, vous pouvez remplacer 'LEFT JOIN (SELECT s.zip, s.username des utilisateurs s) t' par' LEFT JOIN users' (et remplacer 't' par' users' dans le reste du code, bien sûr) . Mais depuis que j'ai donné une solution de travail, je ne vais pas analyser votre nouveau complètement :-) – Binarus