Précédent   Forum des professionnels en informatique > Bases de données > Oracle > SQL
SQL Forum d'entraide sur le SQL pour Oracle
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 23/11/2010, 22h49   #1
Candidat au titre de Membre du Club
 
Inscription : février 2007
Messages : 96
Détails du profil
Informations forums :
Inscription : février 2007
Messages : 96
Points : 13
Points : 13
Par défaut Comment afficher le résultat d’une requête à l’horizontal ?

Salut les amis,

Voilà j’ai une question concernant l’affichage du résultat d’une requête Sql depuis la vertical vers l’horizontal, je m’explique :
J’ai la table table1 contenant les informations ci-dessous :
Code :
1
2
3
4
5
6
 
Nom	Prenom	Num-tel
BR	Alain	555577666
BR	Alain	555344776
BS	Marc	666886655
BS	Marc	666765788
Comme vous pouvez le constater certaines informations se répètent sauf les num-tel.
Ce que Je souhaiterai faire c’est d’interroger cette table de sorte à ressortir le résultat suivant :
Code :
1
2
3
4
 
Nom	Prenom	Num-tel1  Num-tel2
BR	Alain	555577666 555344776
BS	Marc	666886655 666765788
Donc ressortir avec une seule ligne pour chaque Nom qui se répète avec plusieurs colonnes num-tel correspondantes.
Est-ce que c’est possible ??
Merci
mohe27 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/11/2010, 23h04   #2
Membre Expert
 
Avatar de nuke_y
 
Inscription : mai 2004
Messages : 1 812
Détails du profil
Informations forums :
Inscription : mai 2004
Messages : 1 812
Points : 1 609
Points : 1 609
2 solutions:

1) Si tu connais à l'avance le nombre de numéros de téléphones possibles il suffit de faire plusieurs alias de ta table et des les lier sur les champs communs (Nom et Prénom dans ton cas). A noter que s'il n'y a aucun moyen de les différencier (un ID par exemple) tu risques d'avoir des doublons et pour obtenir un résultat propre il va falloir utiliser des fonctions analytiques.

2) Si tu acceptes de réunir tous les numéros de téléphone dans une seule colonne, tu peux détourner une fonction XML:
Code :
1
2
3
4
 SELECT table1."Nom", table1."Prenom"
  rtrim(REPLACE(REPLACE(XMLAGG(XMLElement("x", table1."Num-tel") ORDER BY table1."Num-tel" ASC),'<x>', ''),'</x>', '-'),'-') "Tel List"  
    FROM table1
GROUP BY table1."Nom", table1."Prenom"
Ce qui est fondamental pour te répondre (outre le numéro de version Oracle) c'est donc de savoir s'il peut y avoir 1, 2 ou n numéros de téléphones pour 1 couple Nom + Prénom.
__________________
Il vaut mieux monopoliser son intelligence sur des bêtises que sa bêtise sur des choses intelligentes.

Mon combat pour les droits des consommateurs face aux abus des grandes marques.
nuke_y est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/11/2010, 23h51   #3
Membre actif
 
Yong Huang
Inscription : janvier 2010
Messages : 105
Détails du profil
Informations personnelles :
Nom : Yong Huang

Informations forums :
Inscription : janvier 2010
Messages : 105
Points : 150
Points : 150
J'ai un exemple à
http://yong321.freeshell.org/oranote...ueryResult.txt

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
SQL> SELECT * FROM a;
 
        ID NAME
---------- ----------
         1 David
         2 Yong
 
SQL> SELECT * FROM b;
 
        ID SKILL
---------- --------------------
         1 Java
         1 SQL
         1 Excel
         2 Oracle
         2 SQL
 
SQL> WITH x AS (SELECT row_number() over (partition BY id ORDER BY id) rn, b.* FROM b)
  2  SELECT a.*,
  3   (SELECT skill FROM x WHERE a.id=x.id AND x.rn=1) skill1,
  4   (SELECT skill FROM x WHERE a.id=x.id AND x.rn=2) skill2,
  5   (SELECT skill FROM x WHERE a.id=x.id AND x.rn=3) skill3
  6  FROM a;
 
          ID NAME       SKILL1     SKILL2     SKILL3
------------ ---------- ---------- ---------- ----------
           1 David      Java       SQL        Excel
           2 Yong       Oracle     SQL
yong321 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/11/2010, 09h30   #4
Membre régulier
 
Inscription : septembre 2008
Messages : 84
Détails du profil
Informations forums :
Inscription : septembre 2008
Messages : 84
Points : 88
Points : 88
Un exemple avec une seule requete

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
WITH tab AS (SELECT 'BR' NOM, 'Alain' PRENOM, '555577666' NUMTEL FROM DUAL
Union ALL SELECT 'BR', 'Alain', '555344776' FROM DUAL
Union ALL SELECT 'BS', 'Marc', '666886655'  FROM DUAL
Union ALL SELECT 'BS', 'Marc', '666765788'  FROM DUAL)
SELECT Max(NOM) nom, Max(PRENOM) prenom, 
       Max(DECODE(ORDRE, 1, NUMTEL, NULL)) TEL1, 
       Max(DECODE(ORDRE, 2, NUMTEL, NULL)) TEL2
  FROM (SELECT ROW_NUMBER() OVER(Partition BY NOM, PRENOM ORDER BY NOM, PRENOM) ORDRE, NOM, PRENOM, NUMTEL FROM TAB)
 GROUP BY NOM, PRENOM;
 
NOM PRENOM TEL1      TEL2
--- ------ --------- ---------
BR  Alain  555577666 555344776
BS  Marc   666886655 666765788
spdev666 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/11/2010, 09h37   #5
Membre Expert
 
Avatar de nuke_y
 
Inscription : mai 2004
Messages : 1 812
Détails du profil
Informations forums :
Inscription : mai 2004
Messages : 1 812
Points : 1 609
Points : 1 609
Oui c'est un bon exemple, attention qu'il ne se limite qu'à 3 valeurs.

Attention aussi qu'avec la structure dénormalisée que possède mohe27, il faudra retravailler les résultats pour éviter les doublons.
__________________
Il vaut mieux monopoliser son intelligence sur des bêtises que sa bêtise sur des choses intelligentes.

Mon combat pour les droits des consommateurs face aux abus des grandes marques.
nuke_y est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/11/2010, 10h32   #6
Membre Expert
 
Inscription : avril 2006
Messages : 1 024
Détails du profil
Informations forums :
Inscription : avril 2006
Messages : 1 024
Points : 1 175
Points : 1 175
Si t'es en 11g, tu peux aussi regarder du coté de la clause PIVOT si tu sais caractériser tes colonnes à l'avance.

Pour transformer des données colonnes en ligne, tu as aussi la clause WITHIN GROUP mais SQL ne te donnera pas la possibilité de faire un nombre variable de colonne sauf à faire une fonction qui te renvoit un sys_refcursor (mais se pose toujours le pb de son affichage et de son traitement.)

exemple d'utilisation de LISTAGG/WITHIN GROUP

Code :
1
2
3
4
5
6
7
8
9
10
11
12
WITH tab AS (SELECT 'BR' NOM, 'Alain' PRENOM, '555577666' NUMTEL FROM DUAL
Union ALL SELECT 'BR', 'Alain', '555344776' FROM DUAL
Union ALL SELECT 'BS', 'Marc', '666886655'  FROM DUAL
Union ALL SELECT 'BS', 'Marc', '666765788'  FROM DUAL
Union ALL SELECT 'BS', 'Marc', '666765789'  FROM DUAL)
SELECT
   nom,prenom,
   listagg (NUMTEL, ',') WITHIN GROUP (ORDER BY NUMTEL) liste
FROM 
   tab
GROUP BY 
   nom,prenom
remi4444 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/11/2010, 10h48   #7
Candidat au titre de Membre du Club
 
Inscription : février 2007
Messages : 96
Détails du profil
Informations forums :
Inscription : février 2007
Messages : 96
Points : 13
Points : 13
Bonjour les amis,

et je vous remercie pour ces réponses, cependant j'aurai quelques remarques comme suit:

1ère réponse nuke_y:
ta solution est très bonne et elle prend en compte le nombre 1--n des num-tel que peut posséder un nom unique, le resultat est concaténé en une seule colonne "Tel List" avec "-" comme séparateur entre chaque num-tel, seulement mon besoin est de faire resortir le resultat des num-tel sur des colonnes distinctes.

2ème réponse yong321:
ta solution concrétise bien une sortie correcte des résultat seulement là elle fait appel à 2 tables disrinctes et dans mon cas je ne dispose que d'une seule table.

2ème réponse spdev666:ta solution est excellente seulement elle est figée sur des données precises sur ce que j'ai données en exemple dans la table table1 or celle que je compte interroger rellement contient quelques 30 000 lignes.

Donc le souhait est de faire sortir des resultats sans doublons coté "nom" et "prenom" avec autant de colonnes que necessaires pour le num-tel comme par exemple le tableau ci-dessous:

Code :
1
2
3
4
5
 
Nom	Prenom	Num-tel1  	Num-tel2	Num-tel3
BR	Alain	555577666	555344776	
BS	Marc	666886655	666765788	
BA	Charles	555567000	555898001	555777999
merci à tous
mohe27 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/11/2010, 11h01   #8
Membre Expert
 
Inscription : avril 2006
Messages : 1 024
Détails du profil
Informations forums :
Inscription : avril 2006
Messages : 1 024
Points : 1 175
Points : 1 175
Citation:
Envoyé par mohe27 Voir le message
Donc le souhait est de faire sortir des resultats sans doublons coté "nom" et "prenom" avec autant de colonnes que necessaires pour le num-tel comme par exemple le tableau ci-dessous:
Tu ne t'en sortiras à mon avis pas, à un moment le langage SQL renvoie un curseur et ce curseur a un nombre fixé de colonnes, ça fait partie du système. Tu n'auras pas de notion de "tableau croisé dynamique" comme dans Excel.

Après, tout dépend de ton interface, oracle fourni les données et l'appli cliente est chargée de les mettre en forme, il faut pas trop en demander à SQL.

Donc pour résoudre ton problème, il faut que tu donnes la finalité du truc.

Encore une fois, la solution qui s'approcherait le plus des exemples que tu donnes est d'appeler une fonction qui fa générer dynamiquement une requête et revoyer le tout dans un sys_refcursor. Le SQL*PLUS est alors capable de restituer ce curseur par une variable locale de type "refcursor"

EDIT: mais c'est quand meme une belle usine à gaz!
remi4444 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/11/2010, 11h22   #9
Candidat au titre de Membre du Club
 
Inscription : février 2007
Messages : 96
Détails du profil
Informations forums :
Inscription : février 2007
Messages : 96
Points : 13
Points : 13
ok remi4444,

Et si je fixais le nombre de colonnes num-tel à 5 par exemple, comment pourrais-je sortir un tel resultat selon ce que j'ai illustré plus haut ??

merci
mohe27 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/11/2010, 11h48   #10
Membre Expert
 
Inscription : avril 2006
Messages : 1 024
Détails du profil
Informations forums :
Inscription : avril 2006
Messages : 1 024
Points : 1 175
Points : 1 175
spdev666 et yong321 t'ont déjà répondu.
remi4444 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/11/2010, 12h05   #11
Candidat au titre de Membre du Club
 
Inscription : février 2007
Messages : 96
Détails du profil
Informations forums :
Inscription : février 2007
Messages : 96
Points : 13
Points : 13
Merci remi4444,

et merci à tout le monde, en fait j'ai pris l'exemple de spdev666 que je viens juste de reparamétrer avec les données que j'ai et ce avec requetes sur toute la table . ça marche à merveille

même si tu as un nom avec 3 num-tel et un autre avec 1 ou 2 seulement, la 3ème colonne de ce dernier en ressortira vide

merci encore l'équipe
mohe27 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 09h56.


 
 
 
 
Partenaires

Hébergement Web