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

gc
Eléphanteau du PHP | 46 Messages

06 août 2005, 12:48

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
Modifié en dernier par gc le 06 août 2005, 18:25, modifié 1 fois.

gc
Eléphanteau du PHP | 46 Messages

06 août 2005, 13:09

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... :(

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

06 août 2005, 13:29

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 ;)

gc
Eléphanteau du PHP | 46 Messages

06 août 2005, 13:41

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?

gc
Eléphanteau du PHP | 46 Messages

06 août 2005, 14:57

j'ai essayé différentes requêtes, mais rien à faire...
comment fait-on pour aligner plusieurs sous-requêtes?

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

06 août 2005, 15:00

mais pour 1 mot tu devrais avoir 4 résultats maximum non ?

sinon tu peux combiner plusieurs champs dans un ORDER BY

gc
Eléphanteau du PHP | 46 Messages

06 août 2005, 15:09

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...

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

06 août 2005, 15:23

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

gc
Eléphanteau du PHP | 46 Messages

06 août 2005, 15:29

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...

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

06 août 2005, 15:57

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...

gc
Eléphanteau du PHP | 46 Messages

06 août 2005, 16:07

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...

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

06 août 2005, 17:50

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

gc
Eléphanteau du PHP | 46 Messages

06 août 2005, 17:55

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 :)

Administrateur PHPfrance
Administrateur PHPfrance | 11457 Messages

06 août 2005, 18:00

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. :?

gc
Eléphanteau du PHP | 46 Messages

06 août 2005, 18:24

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! :)