LIKE inversé

VaN
Mammouth du PHP | 1107 Messages

28 nov. 2008, 13:29

Bonjour,

J'ai un bout de requete, que voici :
$sql .= " AND alerte_zipcode LIKE '".$_POST['annonce_zipcode']."'";
que j'aimerai modifier.

La variable $_POST['annonce_zipcode'] va être de la forme 75001, 75002, etc.
Et la valeur de mon champs alerte_zipcode peut être de la forme 75001, ou 75 tout court.

J'aimerai donc opérer une comparaison, pour que la requête me sorte les entrées dont le champ alerte_zipcode est contenu dans $_POST['annonce_zipcode'], et non pas le contraire, comme ferait un LIKE '%".$_POST['annonce_zipcode']."%'".

En gros, il s'agit d'un système d'alertes mails, qui doit récupérer des mails dans la base de données, liées à des alertes enregistrées par des utilisateurs, lorsque cette alerte correspond à une annonce qui vient d'être postée.

Si le code postal ciblé par l'alerte est 75, il faut que la requête récupère les annonces donc le code postal est 75001 ou 75002 par exemple.
Modifié en dernier par VaN le 03 déc. 2008, 13:27, modifié 2 fois.

ViPHP
ViPHP | 2291 Messages

28 nov. 2008, 15:10

Je suis pas certain d'avoir compris :?:
Mais pourquoi pas un siml WHERE :?:
WHERE annonce_zipcode = '".$_POST['annonce_zipcode']."'

VaN
Mammouth du PHP | 1107 Messages

03 déc. 2008, 13:04

Je remonte ce topic, car finalement, je suis à nouveau confronté à ce problème. Post d'origine mis à jour.
Je suis pas certain d'avoir compris :?:
Mais pourquoi pas un siml WHERE :?:
WHERE annonce_zipcode = '".$_POST['annonce_zipcode']."'
J'ai déjà un WHERE plus haut dans la requête. Là, il s'agit seulement du filtre concernant les codes postaux.

Eléphant du PHP | 422 Messages

03 déc. 2008, 13:17

Tu peux faire

Code : Tout sélectionner

$sql .= " AND '".$_POST['annonce_zipcode']."'" LIKE CONCAT ('%', alerte_zipcode,'%');
Maintenant, je te déconseille fortement l'utilisation d'un % en début de chaîne parce que tu vas récupérer tous les 75001, mais aussi tous les 22750 et qu'en cas de base importante, ça va plomber les temps de réponse.

Cela dit, je n'ai pas tout compris à ton truc. Tu dis que le $_POST contient 75001, 75002; le champ alerte_zipcode 75001 ou 75. Mais que tu veux les $_POST qui soient inclus dans les alerte_zipcode. Or je ne vois pas comment 75001 peut être inclus dans 75.

En tous cas, le like que tu donnes sans caractère joker (% ou _) est équivalent à un =

VaN
Mammouth du PHP | 1107 Messages

03 déc. 2008, 13:28

Cela dit, je n'ai pas tout compris à ton truc. Tu dis que le $_POST contient 75001, 75002; le champ alerte_zipcode 75001 ou 75. Mais que tu veux les $_POST qui soient inclus dans les alerte_zipcode. Or je ne vois pas comment 75001 peut être inclus dans 75.
Effectivement, j'ai édité, c'est évidemment l'inverse qui m'intéresse.
Tu peux faire

Code : Tout sélectionner

$sql .= " AND '".$_POST['annonce_zipcode']."'" LIKE CONCAT ('%', alerte_zipcode,'%');
Je test ça dans l'après-midi.

EDIT :
petite retouche du code :
$sql .= " AND '".$_POST['annonce_zipcode']."' LIKE CONCAT('', alerte_zipcode, '%')"; 
ça semble marcher. je vais quand meme faire quelques tests plus poussés. Et j'ai enlevé le % du début, pour eviter des résultats non-pertinents, comme tu l'as souligné.

VaN
Mammouth du PHP | 1107 Messages

05 déc. 2008, 11:47

Bon ça semble bien marcher, sauf dans un cas :

Lorsque mon annonce porte par exemple le code postal 78200, et que mon alerte cible les départements 75 et 78 (stockés en "75, 78" dans la bdd, dans le champs "alerte_zipcode"), la requete n'arrive pas encore à faire la correspondance. Par contre, si l'alerte ne comprend qu'un seul zipcode, même en 2 chiffres, pour indiquer tout un département, ça marche bien. Une idée du pourquoi ?

[Note : ce message a été posté de manière anonyme avant d'être réattribué à son auteur]

ViPHP
ViPHP | 5924 Messages

05 déc. 2008, 12:01

Hé bien tout simplement ta base est mal modélisée. Tu te pourris tes performances et ta maintenabilité en procédant ainsi…
Tu devrais opter pour une seconde table qui fait correspondre à l'id de l'annonce un zipcode. Tu fais ensuite une jointure lors de ta requête pour chercher l'annonce…

Eléphant du PHP | 422 Messages

11 déc. 2008, 13:23

Sans même créer une autre table, mais en incluant le département dans la table des communes.

Je travaille rarement avec les codes postaux (ça change souvent, c'est pas toujours très logique, ...) mais avec les codes insee des communes.
La modélisation des tables que j'utilise est

Code : Tout sélectionner

code_commune nom_commune code_canton code_arrondissement code_departement code_region
Une commune appartenant à un canton qui appartient à un arrondissement qui appartient à un département qui appartient à une région, il est sûr que du point de vue "puriste", l'indication de ces codes dans la table des communes est superflu. On pourrait retrouver la région avec un certain nombre de jointures en remontant toute la chaîne.

Mais d'autre part, ce sont des données qui sont tellement "figées" qu'il ne faut pas hésiter à faire de la redondance d'informations. Et si un jour, une commune change de département, ça demandera peut-être un peu plus de travail pour faire les modifications. Mais on parle là de 5 mn de plus une fois tous les 50 ans. Et encore.

Et pour faire bondir encore plus les tenants de la non-redondance, j'ai même le nom du département dans la table des communes. Quand un département change de nom, ça m'oblige à faire un update du nom dans la table des communes. Mais ça m'évite des millions de jointures entre deux changements de nom.

Note avant de me faire traiter de tous les noms : je n'utiliserais pas ce genre de méthodes non orthodoxes pour les "départements" d'une entreprise, beaucoup susceptibles d'évolutions.