Page 1 sur 1

Classer avec un order by mais pas alphabétiquement

Posté : 26 mars 2006, 21:44
par shi
Pas sûr d'être clair mais en fait j'ai eu le malheur de prendre OVH pour un hébergement mutualisé et ils ne donnent pas accès à la version 4.01 de MySQL et donc pas accès aux interclassement en UTF-8 pour gérer les caractères asiatiques.

J'utilisais la fonction FULLTEXT pour avoir les résultats d'une requête avec un ordre de pertinence mais du coup, les données sont transformées en signes latin incompréhensibles et la fonction FULLTEXT ne marche plus...

Me revoilà donc avec un LIKE ou REGEXP mais le order by se fait par ordre alphabétique et ça ne m'arrange pas. Par exemple :

Il faudrait que tu voies ma maison
La maison est bleue
Maison

Voilà comment seront sorties les résultats pour la recherche du mot 'maison'.

Je voudrais que les lignes commençant par 'maison' sortent en premier puis les lignes suivantes.

J'ai essayé ça :

SELECT * FROM dico WHERE fr REGEXP ('^" .htmlspecialchars(addslashes( $critere )) . "') ORDER BY fr ASC limit ".$depart.",".$na."";

SELECT * FROM dico WHERE fr REGEXP ('" .htmlspecialchars(addslashes( $critere )) . "') AND fr NOT LIKE ('" .htmlspecialchars(addslashes( $critere )) . "%') ORDER BY fr ASC limit ".$depart.",".$na."";

Mais avec la boucle while, je n'arrive pas à gérer l'affichage page par page...

Comment faire ??

Posté : 01 avr. 2006, 15:14
par shi
Personne ne sait comment créer une seul requête qui permettrait d'avoir l'affichage dans l'ordre des deux requêtes ci-dessus ?? Ca serait point possible ?

Posté : 01 avr. 2006, 15:36
par Cyrano
Il y aurait une astuce qui te dépannerait peut-être : crée une table temporaire avec la première requête, et organise ta pagination à partir de la table temporaire sur une seconde requête.

Je ne vois pas vraiment d'autre manière de faire dans l'immédiat :-k

shi

Posté : 01 avr. 2006, 21:23
par Invité
hum, merci Cyrano !

Une chose à laquelle j'avais pensée mais qui ne semblait pas marcher, était de tout convertir en utf-8 dans la table même donc au lieu d'avoir le caractère, avoir son équivalent utf-8 du genre : #1253;

Mais lorsque j'ai essayé avec deux-trois données entièrement en utf-8, la fonction fulltext ne semblait pas marcher plus... Je vais reessayer pour voir.

Sinon, tu parles de créer une array qui contiendrait les données de la première requête ?

Si je faisais 2 boucles while, l'une apres l'autre, ça marchait pas trop mal si ce n'est que la limite d'affichage par page n'était plus censée.

Par exemple :
la première requete retourne 9 résultats, la deuxième retourne 22 résultats.
Chacune de ces deux requêtes est limité à 10.
Le total étant de 31 résultats, il doit y avoir 4 pages mais !
la première page affichera 7+10 donc 17 résultats pour 1 page ! Il reste donc 14 résultats à afficher, soit 2 pages.
De ce fait, il ne faut plus que 3 pages au total pour afficher tous les résultats mais il en affichera 4 ! J'aurai donc un bouton suivant qui mènera vers rien !

Enfin bon, là, c'est plus un problème de requête ! Qu'est-ce qui peut-être le plus facilement réalisable ? travailler sur la requête ou trouver un moyen de calculer le nombre de pages avec une valeur variable par requête ?? Argh...

Posté : 01 avr. 2006, 21:30
par Cyrano
non, je parle pas d'un array mais bien d'une table temporaire avec la requête SQL : CREATE TEMPORARY TABLE

Posté : 01 avr. 2006, 21:58
par Hubert Roksor
Sous MySQL, tu devrais pouvoir utiliser une expression quelconque pour trier les résultats, par exemple:

Code : Tout sélectionner

SELECT * FROM dico WHERE champs REGEXP '^maison' ORDER BY (champs REGEXP '^maison') DESC, fr ASC
Ça m'étonne qu'OVH utilise encore 3.23, tu devrais envoyer un mail au support technique pour leur demander dans combien de temps ils pensent le mettre à jour et pourquoi ce n'est pas déjà le cas. En général, les raisons invoquées sont la stabilité et/ou les performances mais à ma connaissance MySQL 4.1 est à la fois plus stable et plus rapide que 3.23.

Si tu veux utiliser le moteur Full-text de MySQL, tu peux t'inspirer de la méthode employée par Mediawiki et regarder du côté de Sanitizer::normalizeCharReferences. Installe Mediawiki, crée un ou deux articles contenant des caractères spéciaux et regarde le résultat dans la table de recherche ("search" je crois, plus très sûr) pour te faire une idée du résultat, les caractères accentués étant remplacés par leur valeur Unicode encodée en hexadécimal. Mais si tu n'as rien compris à ce que je viens de dire (aucun mal à ça, ce n'est pas un sujet très courant), laisse tomber et demande gentiment à OVH de bouger leurs OVFesses pour upgrader MySQL :)

shi

Posté : 01 avr. 2006, 22:42
par Invité
Merci Cyrano et Hubert Roksor !
SELECT * 
FROM dico 
WHERE champs REGEXP '^maison' 
ORDER BY (champs REGEXP '^maison') DESC, fr ASC
C'est possible ça ?? J'avais essayé un truc plus tordu mais avec une variable qui me retournait la première lettre du critere entrée mais ça n'avait pas l'air de fonctionner ! Mais je vais essayer ça !!

J'ai mailé OVH et la réponse fut : Oui, on va passer à 4.1 mais je ne saurai vous dire quand...

Merci OVH !

Pour ce qui est de mediawiki, je vais regarder ça !

Après, j'ai chopé une fonction qui convertit tous les éléments en leur unicode utf-8. donc si on tape le mot énervé, il retournera la version encodé du 'é' qui sera du genre : 蕩 (ou quelque chose comme ça^^) mais sur les quelques cas que j'ai essayé, la fonction fulltext ne marchait pas plus mais j'ai peut-être oublié une transformation à un endroit ou à un autre...

Disons que c'est gênant parce que pour un dico, avoir le mot qu'on recherche à la 3ème page, ça rend tout de suite le truc moins intéressant ! (et bon, 15000 mots traduits à l'heure actuelle alors, j'ai un peu mal ](*,) ) et changer d'hébergeur juste pour ça, ça ne m'enchante pas non plus...

shi

Posté : 01 avr. 2006, 22:50
par Invité
note : haha, le code que j'ai rentré affiche vraiment un caractère asiatique ! mais il fallait comprendre & # 1 2 3 7 5 ; (sans les espaces)

Posté : 01 avr. 2006, 23:02
par Hubert Roksor
En fait, le truc avec mediawiki c'est qu'il effectue une transformation qui ne fonctionne que dans un sens. Par exemple "c'est l'été" serait transformé en "est f3tf3" (en imaginant que la valeur hexadécimale de é soit 0xF3 et que la longueur minimum des mots soit 2 ou 3). C'est utile pour récupérer les ID des enregistrements, mais pour avoir leur contenu il faut s'adresser à la table originale.