question pour les matheux

  • Auteur de la discussion Auteur de la discussion mf
  • Date de début Date de début
WRInaute discret
salut

voila un tableau à deux colonnes
1|2
1|1
0|2
2|2
0|5
1|5

je souhaiterai classer ses lignes dans l'ordre suivant:
2|2
1|5
1|2
1|1
0|5
0|2

si quelqu'un peu me trouver la formule magique, je seche....
attention ca doit marché même si les colonnes sont inversée donc pas de tri sur colonne 1 puis 2.
merci d'avance

ca va me servir pour réaliser un moteur de recherche avec un début de pertinence pour mon site.
 
WRInaute occasionnel
bah faut bien que tu décides quelle colonne prend le pas sur l'autre...d'aprés les résultat la colonne un est plus important que la 2...
 
WRInaute discret
Bonjour,

Je ne comprend pas bien ta question.

D'après l'ordre que tu donne j'aurais dis :

Select id1,id2 from table order by id1 desc,id2 asc

Mais je ne comprend pas ta phrase :
"attention ca doit marcher même si les colonnes sont inversée donc pas de tri sur colonne 1 puis 2.'


Dans ce cas, pourquoi le couple (1,5) (qui équivaut donc à (5,1)) ne passerait pas premier ?

Peux tu expliquer plus clairement ce que tu souhaites faire ?
 
WRInaute passionné
T'as été voir du coté des fonctions de tris de tableau de google ?
natsort, arsort(), asort(), ksort(), sort() et usort() ... ?
Elles sont bien pratique
 
WRInaute accro
Un bête tri du tableau (de mémoire, c'est la fonction sort) de chaînes de caractères en PHP doit fonctionner. En effet, "2|2" > "1|5" > "1|2". Très simple à faire.
 
WRInaute occasionnel
ecocentric a dit:
Un bête tri du tableau (de mémoire, c'est la fonction sort) de chaînes de caractères en PHP doit fonctionner. En effet, "2|2" > "1|5" > "1|2". Très simple à faire.

C'est ce que j'ai dit, faudrait peut être lire avant de répondre non ? :lol:
 
WRInaute discret
merci pour vos réponse mais c'est pas en php que je veux le faire mais en sql....

je m'explique c'est deux colonnes (voir plus) qui correponde chaqu'une à un mot d'une recherche à plusieur mot
EX : un internaute va tapé ; "poule canard "
ca va me donné 2 colonnes une pour poule, etc...
le chiffre indique le nombre de fois le mot trouvé exacte.
permiere ligne : 1 fois le mot poule et 2 fois le mot poisson
2eme ligne : 1 fois poule et une fois poison
etc...
donc je voudrait afficher en premier la ou tous les mots sont présents et plus il y en a mieux ils la ligne sera placé.et si ils ne sont pas tous présent moins ils y en a, plus mal ils sont placé.
c'est peut-être pas encore très claire pour vous.

je vais quand même jeter un oeil sur les usort et consort, je peut peu-être trier ca hors sql même si je pense pas qu'il y aura ma solution dans ses fonstions.
 
WRInaute discret
ecocentric a dit:
Un bête tri du tableau (de mémoire, c'est la fonction sort) de chaînes de caractères en PHP doit fonctionner. En effet, "2|2" > "1|5" > "1|2". Très simple à faire.

oui mais moi je veux que si on inverse les colonnes ca marche aussi et donc si j'inverse les colonnes dans l'ordre ca doit me donner
2|2
5|1
2|1
voit tu le problème.....
 
WRInaute occasionnel
mf a dit:
oui mais moi je veux que si on inverse les colonnes ca marche aussi et donc si j'inverse les colonnes dans l'ordre ca doit me donner
2|2
5|1
2|1
voit tu le problème.....

:idea: Aahhh, enfin je comprends: en gros, tu veux trier d'abord par le minimum de tes colonnes (desc), puis ensuite par la somme de tes colonnes (desc aussi), c'est ça ??
Une sorte de
Code:
order by min(c1,c2,c3,c4...) desc , sum(c1,c2,c3,c4...) desc
(bon, je sais, là ça marche pas, c'était juste pour essayer de comprendre les critères de tri)
J'ai pigé ?

[edit] Au fait, si c'est comme ça que tu veux trier, essaye ça:
Code:
 SELECT least(col1, col2) as mymini, (col1+col2) as mysum FROM thetable ORDER BY mymini desc, mysum desc
 
WRInaute discret
ecocentric a dit:
ecocentric a dit:
Bein, y doit bien y avoir une fonction en PHP pour inverser un string.

Je me répond : http://be2.php.net/manual/en/function.strrev.php
Donc (pour changer de colonne), t'inverse puis tu tries puis tu re-inverses.

bon bein je rajoute deux lignes qui dans mon objectif va en dernier
2|2
5|1
2|1
50|0
0|30

donc toutes vos solutions ne fonctionne plus.....
mais bon ca doit marché pareil pour 3 ou 4 colonne
3|4|2
5|4|1
1|2|3
0|2|1
6|0|0
bon là cela se complique
en fait l'idée c'est une expression matématique qui avec pour la premier ligne les chiffres 3,4,2 me donne un chiffre toujour plus grand que la même expression pour la ligne suivante, etc... je suis sur qu'un grand matheux aurais une solution
 
WRInaute occasionnel
Euhhh... Ben avec un order by least comme je te dis plus haut, ça marche aussi avec des paires (0,30) et (50,0)... Tu as essayé ce que je te propose ?
 
WRInaute discret
Blini a dit:
mf a dit:
oui mais moi je veux que si on inverse les colonnes ca marche aussi et donc si j'inverse les colonnes dans l'ordre ca doit me donner
2|2
5|1
2|1
voit tu le problème.....

:idea: Aahhh, enfin je comprends: en gros, tu veux trier d'abord par le minimum de tes colonnes (desc), puis ensuite par la somme de tes colonnes (desc aussi), c'est ça ??
Une sorte de
Code:
order by min(c1,c2,c3,c4...) desc , sum(c1,c2,c3,c4...) desc
(bon, je sais, là ça marche pas, c'était juste pour essayer de comprendre les critères de tri)
J'ai pigé ?

[edit] Au fait, si c'est comme ça que tu veux trier, essaye ça:
Code:
 SELECT least(col1, col2) as mymini, (col1+col2) as mysum FROM thetable ORDER BY mymini desc, mysum desc


j'ai pas tous compris dans ton raisonement mais je pense avoir trouvé une solution grace à toi

pour mon exemple avec mes trois colonne je trie chaque ligne par colonne puis chaque colonne pour toutes les lignes.
un exemple vaut mieux qu'un long discourt
au départ
si je reprend mon exemple ci-dessus avec trois colonne
3|4|2
5|4|1
1|2|3
0|2|1
6|0|0
aprs mes tris cela donne
4|3|2
5|4|1
3|2|1
2|1|0
6|0|0
chaque ligne du plus grand au plus petit puis chaque colonne en partant de la dernière vers la première en ordre decroissant
reste à faire le script qui va bien......je me lance.... aie
 
WRInaute discret
Blini a dit:
Euhhh... Ben avec un order by least comme je te dis plus haut, ça marche aussi avec des paires (0,30) et (50,0)... Tu as essayé ce que je te propose ?

oui t'a raison, je connaissais pas la fonction least mais avec trois ou plus de colonne ca coince si ca pouvait trier les colonnes par ligne ca serait bon
 
WRInaute occasionnel
Question: tu as une table SQL qui correspond à ton truc ? Si oui, c'est quoi le nom de la table et le nom des colonnes qui contiennent les comptages ?
 
WRInaute discret
Blini a dit:
Question: tu as une table SQL qui correspond à ton truc ? Si oui, c'est quoi le nom de la table et le nom des colonnes qui contiennent les comptages ?

oui mais non (la table je l'ai mais pas le nombre de colonne...) car le nombre de colonne dépend du nombre de mot que met le gas dans la case de recherche.....5 mots -> 5 colonnes
tu vois....
 
WRInaute occasionnel
Bon, ben tu peux sûrement faire un truc dans le genre, si tu as une variable php type tableau qui contient tes colonnes (on va dire $arrcol):
Code:
strleast = 'LEAST('.implode(',',$arrcol).') as mymin';
strsum = implode('+',$arrcol).' as mysum';
strsql = 'select '.strleast.', '.strsum.' from TABLE order by mymin desc, mysum desc';
mysql_query(strsql);
...
 
WRInaute passionné
mf si par hasard tu comptes "distribuer" ou rendre libre ton programme finis de recherche interne, je suis intéressé.
Il faut que j'en fasse un pour ma nouvelle version, mais j'y ai pas encore réfléchi, mais ta méthode est plutot judicieuse, et comme je vais pas m'auto spammer :) ça serait nikel
 
WRInaute passionné
Hors PHP: en fait c'est un tri par le minimum de chaque ligne, puis par le 2e plus petit élément de la ligne, etc...
Donc en fait:
-commencer par trier les nombres de chaque ligne, disons par ordre croissant
-ensuite trier par ordre décroissant sur la premiere colonne (si ordre croissant ci-dessus, bref la plus petite)
-puis trier les sous-groupes issus du premier tri selon la 2e colonne
-etc...
Astuce: une fois le tri de chaque ligne fait, la transformer en un nombre unique par multiplication selon des puissances de N, par exemple de 10 (ex. 3|1|2 -> 1|2|3 -> 123), en prenant soin de prendre N assez grand et/ou de limiter les chiffres a N-1 pour ne pas tout enmeler.
 
WRInaute discret
tonguide a dit:
mf si par hasard tu comptes "distribuer" ou rendre libre ton programme finis de recherche interne, je suis intéressé.
Il faut que j'en fasse un pour ma nouvelle version, mais j'y ai pas encore réfléchi, mais ta méthode est plutot judicieuse, et comme je vais pas m'auto spammer :) ça serait nikel

euh ca se limite seulement à une requette un peu longue c'est tous
pour le momment.....

c'est juste pour remplacer PHPdig car je trouve cà lourd et tres lent en recherche...
 
WRInaute discret
Blini a dit:
Bon, ben tu peux sûrement faire un truc dans le genre, si tu as une variable php type tableau qui contient tes colonnes (on va dire $arrcol):
Code:
strleast = 'LEAST('.implode(',',$arrcol).') as mymin';
strsum = implode('+',$arrcol).' as mysum';
strsql = 'select '.strleast.', '.strsum.' from TABLE order by mymin desc, mysum desc';
mysql_query(strsql);
...

ca me donne rien car LEAST ressot que la plus petite mais moi je fais pas un tri sur 2 colonnes mais sur X colonne qui n'est pas définie d'ailleur
 
WRInaute discret
si il faut que t'affectes mymin a la colonne A pour avoir ton tableau par l'ordre:

pair 1 -> desc

pair 2 -> desc

il y a une autre solution avec des boucles imbriqués.

voila!
 
WRInaute occasionnel
mf a dit:
ca me donne rien car LEAST ressot que la plus petite mais moi je fais pas un tri sur 2 colonnes mais sur X colonne qui n'est pas définie d'ailleur

Je te comprends pas, mf. D'où tu les sors, tes X colonnes ? Ou bien tu as une table mysql avec des colonnes, et dans ce cas, tu peux connaître le nombre de colonnes, récupérer leurs noms, et construire un tableau $arrcol contenant leurs noms, et appliquer ce que je t'ai dit.
Ou bien, tu parles de X colonnes, mais ce ne sont pas des colonnes au sens table SQL, mais un champ texte qui contient par exemple "5|0|12|8". Avec un nombre de valeurs pas connu à l'avance.
Si c'est ce dernier cas qui correspond à ton problème, j'ai une autre suggestion: à un moment, tu as stocké les valeurs (5, 0, 12, 8) dans ta table SQL, n'est-ce pas ? Bon, ben au lieu de stocker ces valeurs-là, je te propose de modifier ta structure de table:
- un champ "MYMIN"
- un champ "MYSUM"
Quand tu comptes les ocurences des mots, et que tu trouves "5" pour le premier mot, tu fais:
Code:
$mocompte = 5; // le compteur que tu viens de calculer: 5 occurences du mot
$query = 'update matable set MYMIN = LEAST(MYMIN, '.$mocompte.
              '), MYSUM = MYSUM + '.$mocompte;
mysql_query($qurey);
Tu fais pareil pour chaque compte de mots (5, 0, 12, 8).

Ainsi dans ta table, plutôt que de stocker les comptes des différents mots, tu ne stockes que le min et la somme.
Ensuite, pour trier, tu fais:
Code:
select MYMIN, MYSUM from matable order by MYMIN desc, MYSUM desc

Bon bien sûr, là, il manque la clé de ton record pour l'update, mais je pense que tu comprends la philosophie.
Alors, c'est mieux, là ?
 
WRInaute discret
les champs des colones sont des champs calculé donc pas stocké
ma requette calcul pour chaque mot le nombre de fois sa présence et pour chaque mot correspond une colonne calculé.

voila un éxemple de rewuette calculé

Code:
select s.code_societe,s.societe,CONCAT(s.adresse,' ',s.cp,' ',s.ville,' (',p.pays,')' ) , (IF ( s.societe REGEXP '([ ]+electro[ ]+)|(^electro[ ]+)|([ ]+electro$)|(^electro$)', 1, 0 )) +(IF ( s.adresse REGEXP '([ ]+electro[ ]+)|(^electro[ ]+)|([ ]+electro$)|(^electro$)', 1, 0 )) +(IF ( s.ville REGEXP '([ ]+electro[ ]+)|(^electro[ ]+)|([ ]+electro$)|(^electro$)', 1, 0 )) +(IF ( p.pays REGEXP '([ ]+electro[ ]+)|(^electro[ ]+)|([ ]+electro$)|(^electro$)', 1, 0 )) , (IF ( s.societe REGEXP '([ ]+france[ ]+)|(^france[ ]+)|([ ]+france$)|(^france$)', 1, 0 )) +(IF ( s.adresse REGEXP '([ ]+france[ ]+)|(^france[ ]+)|([ ]+france$)|(^france$)', 1, 0 )) +(IF ( s.ville REGEXP '([ ]+france[ ]+)|(^france[ ]+)|([ ]+france$)|(^france$)', 1, 0 )) +(IF ( p.pays REGEXP '([ ]+france[ ]+)|(^france[ ]+)|([ ]+france$)|(^france$)', 1, 0 )) from societe s, pays p where p.code_pays=s.code_lieu and s.validation=1 and ( s.societe like '%electro%' or s.adresse like '%electro%' or s.ville like '%electro%' or p.pays like '%electro%' or s.societe like '%france%' or s.adresse like '%france%' or s.ville like '%france%' or p.pays like '%france%' )


et y a autan de séquence :

Code:
(IF ( s.societe REGEXP '([ ]+france[ ]+)|(^france[ ]+)|([ ]+france$)|(^france$)', 1, 0 )) +(IF ( s.adresse REGEXP '([ ]+france[ ]+)|(^france[ ]+)|([ ]+france$)|(^france$)', 1, 0 )) +(IF ( s.ville REGEXP '([ ]+france[ ]+)|(^france[ ]+)|([ ]+france$)|(^france$)', 1, 0 )) +(IF ( p.pays REGEXP '([ ]+france[ ]+)|(^france[ ]+)|([ ]+france$)|(^france$)', 1, 0 ))
que j'ai de mot clé saisie

tu vois mieux...et ecore une fois que j'aurais résolut se problème je complèxifirais encore la requette....
 
WRInaute occasionnel
Eh ben... C'est pas gagné. Je persiste à dire qu'avec le classement "min desc, sum desc", tu auras ce que tu cherches... Quant à l'adapter à ton code, je baisse les bras.
 
WRInaute passionné
En effet... s'il y a un 0, le min est 0 et donc ca va bien en bas...
Sinon, la méthode qui consisterait a faire un tri croissant par ligne -> conversion en 1 seul nombre -> tri sur ce seul nombre serait bien aussi.
Différences: tri a la fin et non en cours de route pour chaque document; un seul tri final et non un double.
 
WRInaute impliqué
Question bête: pourquoi ne pas simplement utiliser les fonctions de recherche de MySQL (MATCH...AGAINST et les index fulltext) plutôt que de chercher une méthode maison ?
Ok, on peut faire mieux niveau pertinence mais je trouve que les résultats sont quand même pas mauvais et plutôt rapides !
 
WRInaute discret
juste pour dire que j'ai réussi à faire ce que je voulais....
c'est un peu le bronx mais ca marche :P
 
WRInaute discret
enfin je sais pas se que tu pourrais en faire car je peut pas en faire un truc standard c'est trop personalisé avec ma BD et le site :roll:
 

➡️ Offre MyRankingMetrics ⬅️

pré-audit SEO gratuit avec RM Tech (+ avis d'expert)
coaching offert aux clients (avec Olivier Duffez ou Fabien Faceries)

Voir les détails ici

coaching SEO
Haut