[resolu] afficher une fois si il existe déjà

afficher une fois si il existe déjà [resolu] - PHP - Programmation

Marsh Posté le 24-07-2006 à 14:32:12    

Bonjour à tous,  
 
J'ai besoin de vos lumières. J'ai fait un moteur de recherche dans mes user.
Voici la table USER : cle, nom, prenom, filiale.
J'ai une table de liaison LIENFONCTION fonc_cle, uti_cle.
Une table FONCTIONS cle, lib
Une table FILIALES cle, lib
 
je peux chercher mes user par NOM, FONCTION ou FILIALE.
Cela fonctionne bien sauf que quand je fais recherche par entreprise, le meme nom s'affiche plusieurs fois puisqu'il a plusieurs fonctions. Est-ce possible de le faire apparaitre une seule et unique fois dans ma liste??
 
Voici mon code mes permetant d'afficher cette liste après avoir valider mon formulaire de recherche:

Code :
  1. $query = "SELECT utilisateurs.uti_cle, uti_nom, uti_prenom, uti_mail, uti_tel, uti_portable, fil_lib, marq_lib, fonc_lib
  2.     FROM lienfonc
  3.    INNER JOIN utilisateurs ON utilisateurs.uti_cle=lienfonc.uti_cle
  4.    INNER JOIN filiales ON uti_filiale=fil_cle
  5.    INNER JOIN marques ON fil_marque=marq_cle
  6.    INNER JOIN fonctions ON fonctions.fonc_cle=lienfonc.fonc_cle
  7.    WHERE 1=1 ";
  8. $count = "SELECT count(uti_cle) AS cpt
  9.     FROM utilisateurs
  10.    INNER JOIN filiales ON uti_filiale=fil_cle
  11.    INNER JOIN marques ON fil_marque=marq_cle
  12.    INNER JOIN fonctions ON uti_fonction=fonc_cle
  13.    WHERE 1=1 ";
  14. if ($HTTP_GET_VARS['marque']!=0)
  15. {
  16. $condi=$condi . ' AND marq_cle=' .$HTTP_GET_VARS['marque'];
  17. }
  18. if ($HTTP_GET_VARS['filiale']!=0)
  19. {
  20. $condi=$condi . ' AND fil_cle=' .$HTTP_GET_VARS['filiale'];
  21. }
  22. if ($HTTP_GET_VARS['uti_fonction']!=0)
  23. {
  24. $condi=$condi . ' AND fonctions.fonc_cle=' .$HTTP_GET_VARS['uti_fonction'];
  25. }
  26. if (isset($HTTP_GET_VARS['uti_nom']))
  27. {
  28. $trav=strtoupper($HTTP_GET_VARS['uti_nom']);
  29. $condi=$condi . " AND upper(uti_nom) LIKE '%" .$trav. "%'";
  30. }
  31. $query= $query.$condi. ' ORDER BY uti_nom, uti_prenom OFFSET ' . $offset . ' LIMIT 5';
  32. $count=$count.$condi;
  33. $qry=pg_query($conn, $count);
  34. $result=pg_fetch_object($qry);
  35. $nbr=$result->cpt;
  36. $nbpage=$nbr/5;
  37. if (($nbr%5)!=0)
  38. {
  39. $nbpage=$nbpage+1;
  40. }
  41. $qry=pg_query($conn, $query);


Message édité par jenny50 le 24-07-2006 à 16:25:23
Reply

Marsh Posté le 24-07-2006 à 14:32:12   

Reply

Marsh Posté le 24-07-2006 à 14:39:17    

tu ajoute au bout de ta requete  GROUP BY NOM, tu n'aura ainsi qu'un resultat par nom  
 

Reply

Marsh Posté le 24-07-2006 à 14:43:47    

il me met cette erreur :  
Warning: pg_query() [function.pg-query]: Query failed: ERROR: argument of AND must be type boolean, not type character varying in C:contact_grp_result.php on line 63

Reply

Marsh Posté le 24-07-2006 à 14:47:02    

puis ça :  
Warning: pg_query() [function.pg-query]: Query failed: ERROR: column "utilisateurs.uti_cle" must appear in the GROUP BY clause or be used in an aggregate function in C:contact_grp_result.php on line 63

Reply

Marsh Posté le 24-07-2006 à 14:49:47    

tu peux montrer ta requête? Tu as bien mis le group by entre le where et le order? Et tu as pensé à mettre tous les champs selectionnés dans ton group by?
 
Sinon tu as une solution plus simple, tu rajoutes un distinct après ton select:

Code :
  1. SELECT distinct utilisateurs.uti_cle, ...

Message cité 1 fois
Message édité par anapajari le 24-07-2006 à 14:50:20
Reply

Marsh Posté le 24-07-2006 à 14:54:44    

voici la ligne que j'ai changé (l 32 par rapport au code du dessus)

Code :
  1. $query= $query.$condi. ' GROUP BY utilisateurs.uti_cle, uti_nom, uti_prenom, uti_mail, uti_tel, uti_portable, fil_lib, marq_lib, conc_lib, fonc_lib ORDER BY uti_nom, uti_prenom OFFSET ' . $offset . ' LIMIT 5 ';


Reply

Marsh Posté le 24-07-2006 à 14:58:49    

on peut voir toute la requete avec les conditions where toussa toussa :o ... Genre tu fais un print!!!
Mais je continue à le dire un distinct c'est plus mieux !!!
 
Sinon pourquoi tu t'amuses à faire une requete pour compter les enregistrements, alors qu'il existe pg_num_rows ????

Reply

Marsh Posté le 24-07-2006 à 15:09:43    

anapajari a écrit :

tu peux montrer ta requête? Tu as bien mis le group by entre le where et le order? Et tu as pensé à mettre tous les champs selectionnés dans ton group by?
 
Sinon tu as une solution plus simple, tu rajoutes un distinct après ton select:

Code :
  1. SELECT distinct utilisateurs.uti_cle, ...



 
oui , mais en gros ( si j'ai bien compris la requete ) , il fait un  
select distinct nom , fonction , entreprise
 
donc si il utilise le DISTINCT , il aura quand meme des noms en double ( ceux qui sont a des fonctions différentes  )

Reply

Marsh Posté le 24-07-2006 à 15:10:39    

il ne m'affiche plus d'erreur mais ça ne fonctionne pas. mon user apparait autant de fois qu'il a de fonctions.
 
Voici l'echo de ma requete

Code :
  1. SELECT utilisateurs.uti_cle, uti_nom, uti_prenom, uti_mail, uti_tel, uti_portable, fil_lib, marq_lib, conc_lib, fonc_lib FROM lienfonc INNER JOIN utilisateurs ON utilisateurs.uti_cle=lienfonc.uti_cle INNER JOIN concessions ON uti_concession=conc_cle INNER JOIN filiales ON conc_filiale=fil_cle INNER JOIN marques ON fil_marque=marq_cle INNER JOIN fonctions ON fonctions.fonc_cle=lienfonc.fonc_cle WHERE 1=1 AND fil_cle=1 AND upper(uti_nom) LIKE '%%'GROUP BY utilisateurs.uti_cle, uti_nom, uti_prenom, uti_mail, uti_tel, uti_portable, fil_lib, marq_lib, conc_lib, fonc_lib ORDER BY uti_nom, uti_prenom OFFSET 0 LIMIT 5


 
Comment dois-je faire si avec "distinct" c'est plus simple???

Reply

Marsh Posté le 24-07-2006 à 15:12:32    

jenny50 a écrit :

il ne m'affiche plus d'erreur mais ça ne fonctionne pas. mon user apparait autant de fois qu'il a de fonctions.
 
Voici l'echo de ma requete

Code :
  1. SELECT utilisateurs.uti_cle, uti_nom, uti_prenom, uti_mail, uti_tel, uti_portable, fil_lib, marq_lib, conc_lib, fonc_lib
  2. FROM lienfonc INNER JOIN utilisateurs ON utilisateurs.uti_cle=lienfonc.uti_cle INNER JOIN concessions ON uti_concession=conc_cle INNER JOIN filiales ON conc_filiale=fil_cle INNER JOIN marques ON fil_marque=marq_cle INNER JOIN fonctions ON fonctions.fonc_cle=lienfonc.fonc_cle
  3. WHERE 1=1 AND fil_cle=1 AND upper(uti_nom) LIKE '%%'
  4. GROUP BY utilisateurs.uti_cle, uti_nom, uti_prenom, uti_mail, uti_tel, uti_portable, fil_lib, marq_lib, conc_lib, fonc_lib
  5. ORDER BY uti_nom, uti_prenom OFFSET 0 LIMIT 5


 
Comment dois-je faire si avec "distinct" c'est plus simple???


 
GROUP BY utilisateurs.uti_cle, uti_nom, uti_prenom, uti_mail, uti_tel, uti_portable, fil_lib, marq_lib, conc_lib, fonc_lib  
à remplacer par  
GROUP BY utilisateurs.uti_cle, uti_nom, uti_prenom, uti_mail, uti_tel, uti_portable
 
au pasage, je t'invite a regarder la doc de group by , histoire de comprendre ce qu'on veut te faire faire


Message édité par flo850 le 24-07-2006 à 15:13:06
Reply

Marsh Posté le 24-07-2006 à 15:12:32   

Reply

Marsh Posté le 24-07-2006 à 15:16:18    

Citation :

donc si il utilise le DISTINCT , il aura quand meme des noms en double ( ceux qui sont a des fonctions différentes  )


Bah non, sinon il sert à quoi le DISTINCT ? A partir du moment où il rencontre un nom déjà rencontré, il le zap  [:airforceone]  
 
 

Code :
  1. SELECT DISTINCT utilisateurs.uti_cle, uti_nom, uti_prenom, uti_mail, uti_tel, uti_portable, fil_lib, marq_lib, conc_lib, fonc_lib
  2. FROM lienfonc
  3. INNER JOIN utilisateurs ON utilisateurs.uti_cle=lienfonc.uti_cle
  4. INNER JOIN concessions ON uti_concession=conc_cle
  5. INNER JOIN filiales ON conc_filiale=fil_cle
  6. INNER JOIN marques ON fil_marque=marq_cle
  7. INNER JOIN fonctions ON fonctions.fonc_cle=lienfonc.fonc_cle
  8. WHERE 1=1
  9. AND fil_cle=1
  10. AND upper(uti_nom) LIKE '%%'
  11. GROUP BY utilisateurs.uti_cle, uti_nom, uti_prenom, uti_mail, uti_tel, uti_portable, fil_lib, marq_lib, conc_lib, fonc_lib
  12. ORDER BY uti_nom, uti_prenom
  13. OFFSET 0
  14. LIMIT 5


 
Normalement, un simple DISTINCT sur ta clé primaire devrait empêcher l'affichage en plusieurs exemplaires de la ligne avec la clé primaire

Message cité 1 fois
Message édité par DarkHope le 24-07-2006 à 15:19:01
Reply

Marsh Posté le 24-07-2006 à 15:19:30    

si j'éxécute le code ci-dessus j'ai toujours mes users en double, triple...
 
si je remplace de cette manière GROUP BY utilisateurs.uti_cle, uti_nom, uti_prenom, uti_mail, uti_tel, uti_portable, fil_lib, marq_lib, conc_lib, fonc_lib  
à remplacer par  
GROUP BY utilisateurs.uti_cle, uti_nom, uti_prenom, uti_mail, uti_tel, uti_portable
 
il m'indique cette erreur Warning: pg_query() [function.pg-query]: Query failed: ERROR: column "filiales.fil_lib" must appear in the GROUP BY clause or be used in an aggregate function in C:contact_grp_result.php on line 63

Reply

Marsh Posté le 24-07-2006 à 15:28:17    

DarkHope a écrit :

Citation :

donc si il utilise le DISTINCT , il aura quand meme des noms en double ( ceux qui sont a des fonctions différentes  )


Bah non, sinon il sert à quoi le DISTINCT ? A partir du moment où il rencontre un nom déjà rencontré, il le zap  [:airforceone]  


 
SELECT DISTINCT nom  retourne uniquement les noms différents, et c'est ce quy'il faut utiliser si on veut juste les noms
mais  
SELECT DISTINCT nom,fonction retourne tous les couples nom,fonction , et donc potentiellement plusieurs noms
 
 
jenny > que contient la colonne fil_lib ?

Reply

Marsh Posté le 24-07-2006 à 15:33:24    

fil_lib = LE NOM DE LA FILIALE.
 
Si j'execute ma requete simple sans avoir fait un choix dans mon formulaire au préalable, les noms sont en double... Voici cette requete :  

Code :
  1. SELECT distinct utilisateurs.uti_cle, uti_nom, uti_prenom, uti_mail, uti_tel, uti_portable, fil_lib, marq_lib, conc_lib, fonc_lib FROM lienfonc INNER JOIN utilisateurs ON utilisateurs.uti_cle=lienfonc.uti_cle INNER JOIN concessions ON uti_concession=conc_cle INNER JOIN filiales ON conc_filiale=fil_cle INNER JOIN marques ON fil_marque=marq_cle INNER JOIN fonctions ON fonctions.fonc_cle=lienfonc.fonc_cle WHERE 1=1

Reply

Marsh Posté le 24-07-2006 à 15:37:59    

flo850 a écrit :

oui , mais en gros ( si j'ai bien compris la requete ) , il fait un  
select distinct nom , fonction , entreprise
[quotemsg=1412340,8,16927]donc si il utilise le DISTINCT , il aura quand meme des noms en double ( ceux qui sont a des fonctions différentes  )


Avec group by aussi [:spamafote] sauf que distinct est prévu pour ce genre de cas, alors que group by ça sert à autre chose...
Admettons que la requete remonte:


nom       prenom    fonction
A         B         f1
A         B         f2
A         B         f3


Que ce soit avec group by ou distinct étant donné qu'une des données de chaque tuple est différente, on obtient forcément trois résultats.
 

jenny50 a écrit :

si j'éxécute le code ci-dessus j'ai toujours mes users en double, triple...


La fonction associé(fonc_lib) n'est pas la même pour chaque résultat, vir le champs fonc_lib et ça marchera très bien
 

jenny50 a écrit :

il m'indique cette erreur Warning: pg_query() [function.pg-query]: Query failed: ERROR: column "filiales.fil_lib" must appear in the GROUP BY clause or be used in an aggregate function in C:contact_grp_result.php on line 63


Comme je le disais tout à l'heure, tu es obligé de mettre TOUS les champs de ton select ( sauf ceux sur lesquels tu as des fonctions d'aggregation) dans ton group by.
 
Bon jenny, avec l'exemple donné plus haut, quel résultat exactement souhaiterais tu obtenir???
moi j'ai peur que tu souhaites

A          B          f1,f2,f3

:o

Message cité 1 fois
Message édité par anapajari le 24-07-2006 à 16:14:43
Reply

Marsh Posté le 24-07-2006 à 16:05:29    

anapajari a écrit :

Avec group by aussi [:spamafote] sauf que distinct est prévu pour ce genre de cas, alors que group by ça sert à autre chose...
Admettons que la requete remonte:


nom       prenom    fonction
A         B         f1
A         B         f2
A         B         f3


Que ce soit avec group by ou distinct étant donné qu'une des données de chaque tuple est différente, on obtient forcément trois résultats.


 
ce que je voulais lui faire faire c'etait quelque chose du genre  
SELECT nom,prenom,fonction  
FROM  ...
WHERE ...
GROUP BY nom,prenom
 
ainsi on avait un seul nom et un seul prenom et une suel fonction , quel que soit le nombre de fonction de la personne  
 
si le but est de faire  
A          B          f1,f2,f3, ca va etre bcp plus difficile

Reply

Marsh Posté le 24-07-2006 à 16:18:21    

flo850 a écrit :

ce que je voulais lui faire faire c'etait quelque chose du genre  
SELECT nom,prenom,fonction  
FROM  ...
WHERE ...
GROUP BY nom,prenom
 
ainsi on avait un seul nom et un seul prenom et une suel fonction , quel que soit le nombre de fonction de la personne


N'importe quoi ... :o
Elle peut pas marcher ta requete, tu peux pas selectionner fonction sans le mettre dans ton group by OU alors il faut que tu aies un fonction d'aggregation sur ce champs, genre

Code :
  1. SELECT nom,prenom,count(fonction)
  2. FROM  ...
  3. WHERE ...
  4. GROUP BY nom,prenom


Reply

Marsh Posté le 24-07-2006 à 16:21:00    

mysql accepte ces requetes sans broncher, sans meme un message d'erreur ( donc c'est pas completement n'importe quoi )  
 
apres, peut etre que postgresql n'aime pas, mais je n'en ai pas sous la main pour vérifier  
:jap:

Reply

Marsh Posté le 24-07-2006 à 16:25:01    

Ok j'ai viré fonc_lib et tout fonctionne correctement...  
 
Merci à tous de m'avoir aidé et puis je ne connaisais pas "distinct" maintenant je pourrai m'en servir

Reply

Marsh Posté le 24-07-2006 à 16:51:16    

flo850 a écrit :

mysql accepte ces requetes sans broncher, sans meme un message d'erreur ( donc c'est pas completement n'importe quoi )  
apres, peut etre que postgresql n'aime pas, mais je n'en ai pas sous la main pour vérifier  
:jap:


Si c'est complètement n'importe quoi, le résultat remonté n'a aucun "sens". Néanmoins ça marche sous mysql ( ce qui me confirme le bien que je pense de mysql), d'ailleurs c'est même marqué dans la doc que c'est pas standard.
http://dev.mysql.com/doc/refman/5. [...] -ansi.html :

Citation :

1.5.4. Extensions MySQL au standard SQL-92
Le serveur MySQL inclut des extensions que vous ne trouverez probablement pas dans les autres bases de données.
(...)

  • Vous n'êtes pas obligé de nommer toutes les colonnes que vous sélectionnez dans la clause GROUP BY. Cela donne de meilleures performances pour certaines situations spécifiques, mais classiques

(...)


(A noter que je demande à voir l'amélioration des performances ...)
 
Dans tout SGBD qui supporte la norme SQL92, les contraintes sur un group by sont:
   

  • Une colonne utilisée dans une expression de la clause SELECT doit figurer dans la clause GROUP BY. Sinon, l'expression utilisant cette colonne est une fonction d'agrégat.

   

  • Une expression GROUP BY ne peut contenir que des noms de colonne de la liste de sélection, et non les noms servant d'arguments aux agrégats vectoriels.


Reply

Marsh Posté le 24-07-2006 à 17:07:17    

je ne connaissait pas ce point de la norme , et je suis tout à fait d'accord que le resultat n'a pas vraiment de sens ( ou plutot que dans notre cas la partie fonction donnera un resultat non deterministe )  
 
ceci dit, ca marche, donc autant en profiter les rares fois ou cela peut etre utile
:jap:

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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