Page 1 sur 1

TRIER les résultats d'une requête selon (...)

Posté : 06 août 2005, 12:48
par gc
Bonjour à tous.
Voilà j'ai une petite question. J'ai la requête suivante:

Code : Tout sélectionner

$query_tout="SELECT id,fr,jp,romaji,kana FROM vocabulaire WHERE "; $query_tout.="msearch='".$mot_noAccent."' ";//FR exact $query_tout.="OR jp='".$mot."' ";//JP exact $query_tout.="OR romaji='".$mot_romaji."' ";//ROMAJI exact $query_tout.="OR kana='".$mot."' ";//KANA exact //--// $query_tout.="OR msearch LIKE'".$mot_noAccent." %' ";//FR en première position //--// $query_tout.="GROUP BY id ORDER BY LENGTH(fr) ASC LIMIT 3000 ";
Et je voudrait pouvoir ordonner mes résultats de la manière suivante:
afficher d'abord les résultats pour msearch='".$mot_noAccent."', puis ceux pour jp='".$mot."' , ensuite ceux pour romaji='".$mot_romaji."' etc...
est-ce possible de faire ça en une seule requête? Jusqu'à présent je faisais plusieurs requêtes succesives, mais je pense qu'il y a surement un moyen de compacter tout ça.

Merci d'avance pour votre aide. :D

Posté : 06 août 2005, 13:09
par gc
J'ai fait quelques recherches sur le forum, et apparemment on peux faire des sous-requêtes?
Si je fais quelque chose comme ça:

Code : Tout sélectionner

SELECT id, fr, jp, romaji, kana FROM vocabulaire Tout INNER JOIN ( SELECT id AS id_fr FROM vocabulaire WHERE msearch = 'chat' ORDER BY LENGTH( msearch ) ASC LIMIT 3000 )Tfr ON Tfr.id_fr = Tout.id INNER JOIN ( SELECT id AS id_jp FROM vocabulaire WHERE jp = 'chat' ORDER BY LENGTH( jp ) ASC LIMIT 3000 )Tjp ON Tjp.id_jp = Tout.id INNER JOIN ( SELECT id AS id_fr2 FROM vocabulaire WHERE msearch LIKE 'chat %' ORDER BY LENGTH( msearch ) ASC LIMIT 3000 )Tfr2 ON Tfr2.id_fr2 = Tout.id ORDER BY id_fr, id_jp, id_fr2 ASC LIMIT 3000
Ca pourrait marcher?
Quand je fait la requête, je n'ai pas d'erreur, mais aucun résultats par contre... :(

Posté : 06 août 2005, 13:29
par ouckileou
la deuxième requête me parait franchement compliquée...

dans ton premier message, inutile de mettre le PHP, ça ne fait qu'embrouiller, laisse juste le code SQL

et puis, explique à quoi correspondent tes données, et les critères de classement parceque "$mot_romaji"...

comme ça on verra si tu peux faire ça dans un simple ORDER BY ou non ;)

Posté : 06 août 2005, 13:41
par gc
la deuxième requête me parait franchement compliquée...

dans ton premier message, inutile de mettre le PHP, ça ne fait qu'embrouiller, laisse juste le code SQL

et puis, explique à quoi correspondent tes données, et les critères de classement parceque "$mot_romaji"...

comme ça on verra si tu peux faire ça dans un simple ORDER BY ou non ;)
OK.

En fait j'ai une table de vocabulaire, avec notemment les champs suivants:
FR = traduction en français du mot
JP = traduction en kanji du mot
KANA = traduction en kana du mot
ROMAJI = traduction en romaji du mot

Code : Tout sélectionner

SELECT id, fr, jp, romaji, kana FROM vocabulaire WHERE fr = 'chat' OR jp = 'chat' OR romaji = 'chat' OR kana = 'chat'
Dans un premier temps, je veux rechercher un mot dans tout ces champs, mais il faut absolument ordonner les résultats de façon à ce qu'apparraissent d'abord les mots trouvés dans FR, puis ceux trouvés dans JP, puis ceux trouvés dans KANA, puis ceux trouvés dans ROMAJI:

Code : Tout sélectionner

résultat 1 dans FR résultat 2 dans FR résultat 3 dans FR résultat 4 dans FR résultat 1 dans JP résultat 2 dans JP résultat 3 dans JP résultat 4 dans JP résultat 1 dans KANA résultat 2 dans KANA résultat 3 dans KANA résultat 4 dans KANA résultat 1 dans ROMAJI résultat 2 dans ROMAJI résultat 3 dans ROMAJI résultat 4 dans ROMAJI

Jusqu'à présent je faisais donc 4 requetes consécutives pour obtenir ce résultat. Maintenant je voudrias si possible tout mettre dans une seule requête.
Pourrait-on donc faire plusieurs sous-requetes à la place?

Posté : 06 août 2005, 14:57
par gc
j'ai essayé différentes requêtes, mais rien à faire...
comment fait-on pour aligner plusieurs sous-requêtes?

Posté : 06 août 2005, 15:00
par ouckileou
mais pour 1 mot tu devrais avoir 4 résultats maximum non ?

sinon tu peux combiner plusieurs champs dans un ORDER BY

Posté : 06 août 2005, 15:09
par gc
mais pour 1 mot tu devrais avoir 4 résultats maximum non ?
non, il faut imaginer qu'il puisse y avoir un nombre illimité de résultats. Car là il s'agit juste d'un exemple, après j'aurais aussi des requête avec des LIKE ...
sinon tu peux combiner plusieurs champs dans un ORDER BY
pour obtenir ça? :

Code : Tout sélectionner

résultat 1 dans FR résultat 2 dans FR résultat 3 dans FR résultat 4 dans FR résultat 1 dans JP résultat 2 dans JP résultat 3 dans JP résultat 4 dans JP résultat 1 dans KANA résultat 2 dans KANA résultat 3 dans KANA résultat 4 dans KANA résultat 1 dans ROMAJI résultat 2 dans ROMAJI résultat 3 dans ROMAJI résultat 4 dans ROMAJI
Je ne pense pas, non...

Posté : 06 août 2005, 15:23
par ouckileou
si tu récupères dans ta requête les libellés de langues, tu pourra sle fair, puisque tu souhaites un classement alphabétique finalement, puis un sous-classement dans chaque langue

mais là je ne vois pas trop

Posté : 06 août 2005, 15:29
par gc
si tu récupères dans ta requête les libellés de langues, tu pourras le fair, puisque tu souhaites un classement alphabétique finalement, puis un sous-classement dans chaque langue
Non, j'ai du mal m'exprimer.

reprenons ma requête:

Code : Tout sélectionner

SELECT id, fr, jp, romaji, kana FROM vocabulaire WHERE fr = 'chat' OR jp = 'chat' OR romaji = 'chat' OR kana = 'chat'
il faudrait d'abord afficher uniquement les résultats de WHERE fr = 'chat', tous à la suite, puis ensuite, tous ceux de WHERE jp = 'chat', etc...

comme si je faisais deux requête successives:

Code : Tout sélectionner

SELECT id, fr, jp, romaji, kana FROM vocabulaire WHERE fr = 'chat' (...) résultat 1 pour fr = 'chat' résultat 2 pour fr = 'chat' résultat 3 pour fr = 'chat' (...) SELECT id, fr, jp, romaji, kana FROM vocabulaire WHERE jp = 'chat' (...) résultat 1 pour jp = 'chat' résultat 2 pour jp = 'chat' résultat 3 pour jp = 'chat' (...)
Ce que je dois ordonner ce ne ont pas les résultats en eux-même, mais la façon dont ils ont été générés...

Posté : 06 août 2005, 15:57
par ouckileou
je crois que j'ai compris, mais si tu regardes ça revient à un premier tri alphabétique sur la langue non ?

fr, jp, romaji, kana

or dans l'alphabet
F avant J avant K avant R

c'est cet ordre que tu m'as montré c'est bien ça ?

donc en récupérant une ligne de résultat de ce type :
id_mot, mot, langue

tu peux faire un tri sur langue, puis sur id_mot pour avoir l'ordre d'enregistrement
mais pour faire ça il faudrait connaitre à quelle langue appartient chaque mot tu vois ?

c'est une piste, je ne sais pas si c'ets réalisable j'ai un peu de mal à me mettre dedans...

Posté : 06 août 2005, 16:07
par gc
je crois que j'ai compris, mais si tu regardes ça revient à un premier tri alphabétique sur la langue non ?

fr, jp, romaji, kana

or dans l'alphabet
F avant J avant K avant R

c'est cet ordre que tu m'as montré c'est bien ça ?

donc en récupérant une ligne de résultat de ce type :
id_mot, mot, langue

tu peux faire un tri sur langue, puis sur id_mot pour avoir l'ordre d'enregistrement
mais pour faire ça il faudrait connaitre à quelle langue appartient chaque mot tu vois ?

c'est une piste, je ne sais pas si c'ets réalisable j'ai un peu de mal à me mettre dedans...
mais non!!! LOL

On recommence:

J'ai donc une table avec plusieurs colonnes, dont entre autre:
ID , FR , JP , KANA (on va zapper les autres pour faire plus simple).

Disons que je veuille rechercher si un terme est présent dans ma table (dans les colonnes FR, JP et KANA), je ferais une requete du style:
SELECT * FROM matable
WHERE fr LIKE '%un_terme%'
OR jp LIKE '%un_terme%'
OR kana LIKE '%un_terme%'
Jusque là, pas de problème.
Maintenant, je veux savoir dans quelle colonne a été trouvé le terme, et afficher mon résultat sous forme de liste par exemple, en ordonnant le tout en fonction de la colonne où a été trouvé le terme.
>>Ainsi, d'abord afficher TOUS les résultats quand le terme a été trouvé dans la colonne FR, puis TOUS les résultats quand le terme a été trouvé dans la colonne JP, puis dans la colonne KANA:

ID - FR - JP - KANA (1er résultat trouvé dans FR)
ID - FR - JP - KANA (2eme résultat trouvé dans FR)
ID - FR - JP - KANA (3eme résultat trouvé dans FR)
etc.
ID - FR - JP - KANA (1er résultat trouvé dans JP)
ID - FR - JP - KANA (2eme résultat trouvé dans JP)
ID - FR - JP - KANA (3eme résultat trouvé dans JP)
etc.
ID - FR - JP - KANA (1er résultat trouvé dans KANA)
ID - FR - JP - KANA (2eme résultat trouvé dans KANA)
ID - FR - JP - KANA (3eme résultat trouvé dans KANA)
etc.
Il n'est pas question de tri alphabetique, mais de tri en fonction de la colonne dans lequel le mot a été trouvé. Que le F soit avant le J et le K c'est un pur hasard. Ca pourrait très bien être d'abord KANA, puis FR, puis JP. C'est purement arbitraire.

J'espère que c'est plus clair comme ça...

Posté : 06 août 2005, 17:50
par ouckileou
oui c'est bien ce que j'avais compris

mais l'ordre dans lequel tu avais mis tes résultats était alphabétique sur les noms de colonnes (et pas sur les mots on est d'accord), c'est pour ça que j'imaginais cette solution, en associant à chaque résultat le nom de la colonne dans lequel il a été trouvé

donc ce que je disais n'était pas si débile que ça, maintenant si tu ne veux pas classer des résultats dans l'ordre alphabétique des colonnes, effectivement ça ne fonctionne pas

autre piste : tu introduis dans ta requête un champ de sortie "virtuel", que tu va remplir toi-même, en fonction de la colonne où a été trouvé le mot
s'il est trouvé dans la colone FR, tu mets ce champ à 1, puisque tu veux ces résultats en premier
avec un CASE par exemple : http://dev.mysql.com/doc/mysql/fr/case-statement.html

je ne sais pas si je suis très clair

maintenant je reconnais que j'ai un peu de mal à me mettre dans ton problème, mais je cherche des solutions pour le faire directement en SQL

Posté : 06 août 2005, 17:55
par gc
C'est bon, j'ai trouvé la solution :)
ça donne ça par exemple:

Code : Tout sélectionner

SELECT id, fr, jp, romaji, kana, img, IF ( msearch = 'chat', '01', IF ( jp = 'chat', '02', IF ( kana = 'chat', '03', IF ( romaji = 'chat', '04', IF ( msearch LIKE 'chat %', '05', IF ( msearch LIKE '% chat %', '06', IF ( msearch LIKE '% chat', '07', IF ( jp = 'chatする', '08', IF ( kana = 'chatする', '09', IF ( romaji = 'chatsuru', '10', IF ( jp = 'chat', '11', IF ( kana = 'chat', '12', IF ( romaji = 'chat', '13', IF ( jp = 'chat', '14', IF ( kana = 'chat', '15', IF ( romaji = 'chat', '16', IF ( msearch = 'chat', '17', IF ( msearch = 'chats', '18', IF ( msearch = 'chatx', '19', IF ( msearch = 'chate', '20', IF ( msearch LIKE 'chats %', '21', IF ( msearch LIKE 'chatx %', '22', IF ( msearch LIKE 'chate %', '23', IF ( msearch LIKE '% chats %', '24', IF ( msearch LIKE '% chatx %', '25', IF ( msearch LIKE '% chate %', '26', IF ( msearch LIKE '% chats', '27', IF ( msearch LIKE '% chatx', '28', IF ( msearch LIKE '% chate', '28', IF ( id = 'chat', '100', NULL )))))))))))))))))))))))))))))) AS colonne FROM vocabulaire HAVING colonne IS NOT NULL ORDER BY colonne ASC LIMIT 1000
ca marche nickel :)

Posté : 06 août 2005, 18:00
par albat
ouckileou a pris la précaution de te proposer d'utiliser l'instruction case.
Ce serait bien que tu l'utilises parce que ta requête est complètement indigeste avec tous ces if. :?

Posté : 06 août 2005, 18:24
par gc
ouckileou a pris la précaution de te proposer d'utiliser l'instruction case.
Ce serait bien que tu l'utilises parce que ta requête est complètement indigeste avec tous ces if. :?
ah oui c'est vrai, j'avais pas bien lu son message.
Merci à tous! :)