[PHP] select avec plein de parametres

select avec plein de parametres [PHP] - PHP - Programmation

Marsh Posté le 07-12-2002 à 23:43:51    

Bonjour,
 
voila mon probleme, j'ai une table de la sorte
 
id_lien I id_user I valeur
110     I  5      I  2
110     I  9      I  4
115     I  5      I  1
115     I  65     I  3
115     I  57     I  1
 
Comment dois-je ecrire la commande pour traiter :
 
1- pour obtenir l' id_lien qui est le plus present (qui a le plus grand nombre de ligne) il me faut récupérer en meme temps le nombre de ligne et le numéro d' id_lien
 
2- pour obtenir l'id_lien qui a la moyenne de valeur la plus élevé (c a d que je souhaite récupérer l' id_lien donc la somme des valeurs divisée par le nombre de lignes est le plus élévé) il me faut récupérer l' id_lien et cette moyenne.
 
Comment dois-je donc orthographier ces commandes pour récupérer ces valeurs ??
 
Merci d'avance.

Reply

Marsh Posté le 07-12-2002 à 23:43:51   

Reply

Marsh Posté le 08-12-2002 à 00:11:48    

Je suppose que c'est pas du PHP, mais du MySql !
 
Donc pour le 1:
 

SELECT id_lien, COUNT(*) AS nombre FROM MA_TABLE GROUP BY id_lien ORDER BY by nombre DESC


Le premier enregistrement est le bon !
 
Pour le 2, même principe :
 

SELECT id_lien, AVG(*) AS nombre FROM MA_TABLE GROUP BY id_lien ORDER BY by nombre DESC


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 08-12-2002 à 00:36:14    

Merci beaucoup c'est parfait.
 
Encore une petite question, comment faire pour arrondir la moyenne à 0,5 pres (en gros il me donne 4,1 -> il doit arrondir a 4, il donne 4,4 -> il donne 4,5 et si il donne 4,8 -> il donne 5)
 
Comment faire, est ce que l'on peut faire ca aussi en meme temps dans la commande ???
Et si non comment faire alors en PHP.
 
Merci d'avance

Reply

Marsh Posté le 08-12-2002 à 00:48:13    

Utlise la fonction ROUND() de MySql.
 
Donc :  
 

SELECT id_lien, AVG(valeur) AS nombre, ROUND(AVG(valeur)) as moyenne FROM MA_TABLE GROUP BY id_lien ORDER BY by nombre DESC


 
J'ai fait la différence entre nombre et moyenne, pour que les enregistrement soit triés sur la vrai Moyenne.
 
Une question : çà t'arrive de lire les docs ? ? ?


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 08-12-2002 à 01:14:53    

Ok pour la fonction round mais ca arrondi au chiffre pres, moi il me faudrait plutot un arrondi a 0,5; dans la doc (je la lis quand meme :-)) j'ai trouvé un arrondi a 0,1 pres mais pas à 0,5
 
Est ce que tu sais si c'est possible ?

Reply

Marsh Posté le 08-12-2002 à 01:17:52    

Ok, cette fois, on le fait en PHP OK !
 
Ben, moi je ferais un truc du genre :
 
$Moyenne = round( $Moyenne * 2 ) / 2;
 
Futté non ?


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 08-12-2002 à 01:32:11    

Ok bien vu, je crois qu'il faut vraiment que je me couche là, je deviens con avec l'heure.
 
Merci encore de ta patience.

Reply

Marsh Posté le 08-12-2002 à 23:04:27    

Je bloque encore, a partir des infos que j'ai recuperer dans ce topic j'ai continué a modifier la commande pour obtenir ce que je veux.
 
En plus de la table du haut, j'en ai une autre
 
id I liens I comments I etat
4  I truc  I  bidule  I 1
2  I truc  I  bidule  I 0
 
J'ai donc croisé les deux tables pour obtenir une requete brassée avec cette formule
SELECT `liens_vote`.`id_lien`, AVG(liens_vote.valeur) AS nombre, ROUND(AVG(liens_vote.valeur),1) as moyenne FROM `liens_vote`,`liens_2` WHERE liens_vote.id_lien=liens_2.id AND liens_2.etat=1 GROUP BY `liens_vote`.`id_lien` ORDER BY nombre DESC
 
Donc celle-ci marche tres bien, elle me renvoi la réponse qui a un etat a 1 et qui a la plus grosse moyenne de valeur
 
Maintenant, je souhaiterai obtenir tous les lignes de la table 2 qui correspondent a des points particuliers et ordonné en fonction de la moyenne de leur note :
 
SELECT liens_2.*, AVG(liens_vote.valeur) AS nombre, ROUND(AVG(liens_vote.valeur),1) AS moyenne FROM `liens_vote`,`liens_2` WHERE liens_vote.id_lien=liens_2.id AND liens_2.etat=1 AND liens_2.liens LIKE '$search2' OR liens_vote.id_lien=liens_2.id AND liens_2.etat='1' AND liens_2.comments LIKE '$search2' GROUP BY `liens_vote`.`id_lien` ORDER BY moyenne $sens, liens_2.liens $sens"
 
J'ai essayé ca qui me renvoi les lignes comme je le souhaite sauf qu'il n'y a que celle qui ont des valeurs dans la table 2
Comment faire pour qu'il me renvoie aussi les lignes qui repondent aux criteres mais qui n'ont pas forcement de valeurs dans la table 2
 
Merci d'avance
 

Reply

Marsh Posté le 09-12-2002 à 07:47:14    

up

Reply

Marsh Posté le 09-12-2002 à 10:26:42    

Cherche les mots "LEFT JOIN" dans ce forum il me semble que de ça que t'as besoin, mais comme je l'ai jamais utilisé, je sais plus s'il faut pas modifier légèrement l'agencement des conditions comme j'ai pu le voir avec access ou si toutes les conditions restent dans le where et le having de la requête.
 
Avec ça t'auras les exemples et les explications dont t'as besoin.

Reply

Marsh Posté le 09-12-2002 à 10:26:42   

Reply

Marsh Posté le 09-12-2002 à 20:45:49    

J'ai regardé la fonction mais je ne m'en sort pas, est ce que quelqu'un peut me donner un coup de pouce ??
 
Merci d'avance

Reply

Marsh Posté le 09-12-2002 à 20:54:26    

sanglochon a écrit :

J'ai regardé la fonction mais je ne m'en sort pas, est ce que quelqu'un peut me donner un coup de pouce ??
 
Merci d'avance

Je vais t'aider à ma façon :
JJJJJJJJJJJJJJOOOOOOOOOOOOCCCCCCCCCCEEEEEEEEEEEEEEE
 
"Le petit Joce est demandé dans ce topic." ;)

Reply

Marsh Posté le 09-12-2002 à 21:57:14    

Déjà, y'a 2 problèmes:
 
1- Une fois, tu met :  
liens_2.etat=1  
et ensuite :
liens_2.etat='1'
 
2- Ensuite, tu mélange des AND et un OR ! Je ne suis pas certain de savoir ce que tu veux faire, mais à ta place, je mettrai des parenthèse pour expliciter.
 
 
Enfin, il faut utiliser le LEFT JOIN, comme çà :
 


SELECT
    liens_2.*,
    AVG(liens_vote.valeur) AS nombre,
    ROUND(AVG(liens_vote.valeur),1) AS moyenne
FROM
    liens_vote LEFT JOIN liens_2 ON liens_vote.id_lien=liens_2.id
WHERE
    liens_2.etat=1
    AND
    (
        liens_2.liens LIKE '$search2'
        OR liens_2.comments LIKE '$search2'
    )
GROUP BY
    liens_vote.id_lien
ORDER BY
    moyenne $sens,
    liens_2.liens $sens


 
Bon, c'est mon interprétation de ce que tu veux, hein !
Je ne suis pas certain de mon coup là !
 
As-tu remarqué comment je présente une requête SQL un peu compliquée ?
C'est quand même plus lisible comme çà non ?


Message édité par Mara's dad le 09-12-2002 à 21:59:09

---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 09-12-2002 à 22:45:47    

Effectivement c'est plus clair comme ca mais ca ne marche pas car je n'ai pas ete suffisamment clair sur mes besoins
 
Je vais essayer d'etre plus clair :
 
J'ai une base liens_2 qui contient plusieurs colonnes dont ID et ETAT
J'ai une base liens_vote qui contient plusieurs colonnes dont ID_LIEN
 
Je souhaite obtenir une requete qui repondent a plusieurs regles
- je respecte les criteres de recherche (ca ca marche avec les LIKE)
- je respecte le fait d'avoir ETAT=1 (ca aussi ca marche)
- je joins la moyenne des VALEUR de LIENS_VOTE avec les lignes en rapport dans LIENS_2 et ce uniquement si elles existent. Si je n'ai pas de lignes dans LIENS_VOTE qui correspondent a LIENS_2 il faut quand meme que ma requete selectionne les lignes qui repondent aux autres criteres precedents et que la moyenne de VALEUR soit mise a 0
 
J'espere que j'ai ete plus clair :-)


Message édité par sanglochon le 09-12-2002 à 22:54:33
Reply

Marsh Posté le 09-12-2002 à 22:51:39    

Heu, oui, c'est ce que j'ai écrit !
 
Celà veut-il dire que j'ai bon ?


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 09-12-2002 à 22:55:35    

desole j'ai fait une fausse manoeuvre, j'etais en train d'editer le message :-)

Reply

Marsh Posté le 10-12-2002 à 19:41:49    

J'ai continué de modifier ce "@[|^[#{ç de code j'ai ca pour le moment

Code :
  1. SELECT
  2. liens_2.*,
  3. AVG(liens_vote.valeur)AS nombre,
  4. ROUND(AVG(liens_vote.valeur),1) AS moyenne
  5. FROM
  6. liens_2
  7. LEFT JOIN
  8. liens_vote
  9. ON
  10. liens_2.id=liens_vote.id_lien
  11. WHERE
  12. liens_2.etat=1
  13. AND
  14. (liens_2.liens LIKE '$search2'
  15. OR liens_2.comments LIKE '$search2')
  16. GROUP BY
  17. liens_2.id
  18. ORDER BY
  19. liens_vote.valeur $sens,
  20. moyenne $sens
  21. LIMIT
  22. $val,$nb_ligne


 
Alors cette formule regle le probleme de non selection des lignes de liens_2 qui n'ont pas de correspondance avec les lignes de liens_vote
 
Par contre que je regle l'affichage en DESC ou ASC, les lignes dont l'équivalence dans liens_vote n'existe pas sont toujours classés avant celles qui existent par contre, il classe bien les valeur dans l'ordre voulu.
 
Aidez moi à finir please  :heink:

Reply

Marsh Posté le 10-12-2002 à 23:24:19    

A mon avis, c'est à cause de :
 
GROUP BY
  liens_2.id
 
Ca fout le bordel quand les enregs de lien_2 n'éxistent pas.
 
Essayes avec :
 
GROUP BY
  liens_vote.id_lien
 
J'y crois pas trop, mais je suis pas certain qu'il y ait une solution en une seule requête !


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 11-12-2002 à 12:18:59    

Ca doit être du aux NULL qui comme ils ne peuvent pas être comparait aux autres doivent être géré diféremment au niveau des tris.
 
C'est pas des plus logique mais c'est ainsi.
 
Avec sybase, il y a une fonction nomé isnull(valeur1,valeur2) qui retourne valeur2 quand valeur1= NULL et valeur1 dans tout les autres cas. C'est utile pour forcer à 0 les colones numérique qui contiennent des valeurs nulles.
 
Faut voir s'il y a un équivalent avec ta base de donné.

Reply

Marsh Posté le 11-12-2002 à 20:27:48    

Comment faire alors si je ne peux le faire en une seule commande pour obtenir un classement par ordre de moyenne ??

Reply

Marsh Posté le 12-12-2002 à 10:35:29    

sanglochon a écrit :

Comment faire alors si je ne peux le faire en une seule commande pour obtenir un classement par ordre de moyenne ??

Tu peux faire en deux requêtes :
une qui ramène ceux qui n'ont pas de null et une qui ramène ceux avec les null.
Ensuite, tu met ceux qui ont des null avant ou après ceux sans les null selon le classement que t'as besoin. ;)

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed