1
votes

Sql Pivot: afficher les champs verticalement

J'essaie de créer une requête où les données s'affichent essentiellement horizontalement par opposition à verticalement. Je crois que c'est appelé pivot (je suis un peu nouveau dans ce domaine). Considérer ce qui suit: Je peux interroger les adresses d'un élève et elles s'afficheraient comme

SELECT Id,
MAX(CASE WHEN rownum =1 THEN B.EMAIL_ADDRESS END) AS "Email1",
MAX(CASE WHEN rownum =2 THEN B.EMAIL_ADDRESS END) AS "Email2",
MAX(CASE WHEN rownum =3 THEN B.EMAIL_ADDRESS END) AS "Email3",
MAX(CASE WHEN rownum =4 THEN B.EMAIL_ADDRESS END) AS "Email4"
FROM MyTable B
where B.Id in (21538) 
group by B.Id

Je préférerais que les données soient affichées horizontalement comme

ID  Email1          Email2               Email3
27  jd@yahoo.com    johndoe47@gmail.com  MrDoe@hotmail.com

J'ai accompli ceci avec la requête ci-dessous pour une personne.

ID    Email
27    jd@yahoo.com
27    johndoe47@gmail.com
27    MrDoe@hotmail.com

Cela fonctionne pour une personne et principalement parce que j'utilise rownum. La valeur sous la colonne Entry4 serait nulle dans cet exemple. Je sais que je suis proche, mais je ne sais pas comment le faire fonctionner pour plusieurs étudiants et arrêter d'utiliser rownum. Toute aide à ce sujet serait grandement appréciée. Merci d'avance


0 commentaires

3 Réponses :


0
votes

Si vous en voulez trois, vous pouvez utiliser l'agrégation conditionnelle

select id,
       max(case whens seqnum = 1 then email end) as email1,
       max(case whens seqnum = 2 then email end) as email2,
       max(case whens seqnum = 3 then email end) as email3
from (select t.*, row_number() over (partition by id order by email) as seqnum
      from t
     ) t
group by id;


3 commentaires

Salutations, je pense que cela fonctionne le mieux. Il donne les e-mails de manière verticale. J'ai essayé de manipuler la requête pour inclure également le type d'e-mail. Chaque adresse e-mail a un type d'e-mail. Donc ce serait quelque chose comme


@ user1898629. . . Ajoutez simplement des colonnes supplémentaires avec max () en utilisant le type au lieu de email .


Merci pour votre aide sur ce problème. J'ai pu produire ce dont j'avais besoin



0
votes

Si vous ne vous souciez pas des colonnes (car une telle chose ne se met pas à l'échelle), pensez à listagg qui vous permet de "concaténer" jusqu'à 4000 caractères de e -adresses de messagerie.

Par exemple (notez que les lignes 1 à 10 représentent des exemples de données; vous l'avez déjà dans votre tableau, la requête que vous voudrez peut-être considérer commence à la ligne 11):

<snip>
 11  select id,
 12    listagg(rpad(email, 20, ' '), ' | ') within group (order by email) email
 13  from test
 14  group by id
 15  order by id;

        ID EMAIL
---------- ----------------------------------------------------------------------
        13 bigfoot@net.hr
        25 foot@gmail.com       | little@hotmail.com
        27 MrDoe@hotmail.com    | jd@yahoo.com         | johndoe47@gmail.com

SQL>

Ou, un peu plus joli (avec rpad):

SQL> with test (id, email) as
  2    (select 27, 'jd@yahoo.com'        from dual union all
  3     select 27, 'johndoe47@gmail.com' from dual union all
  4     select 27, 'MrDoe@hotmail.com'   from dual union all
  5     --
  6     select 25, 'little@hotmail.com'  from dual union all
  7     select 25, 'foot@gmail.com'      from dual union all
  8     --
  9     select 13, 'bigfoot@net.hr'      from dual
 10    )
 11  select id,
 12    listagg(email, ', ') within group (order by email) email
 13  from test
 14  group by id
 15  order by id;

        ID EMAIL
---------- ----------------------------------------------------------------------
        13 bigfoot@net.hr
        25 foot@gmail.com, little@hotmail.com
        27 MrDoe@hotmail.com, jd@yahoo.com, johndoe47@gmail.com

SQL>


0 commentaires

0
votes

Vous pouvez générer vos catégories d'e-mails (Email1, Email2, etc.), puis les utiliser dans une clause PIVOT. Assurez-vous cependant de coder suffisamment de catégories dans le PIVOT. (Par exemple, lors de l'utilisation de la requête suivante: si quelqu'un a 5 adresses e-mail, l'une de ses adresses ne sera pas dans le jeu de résultats.)

select *
from (
  select id, email
  , 'Email' || row_number() over ( partition by id order by email ) emailcategory_
  from emailaddresses
)
pivot (
  max( email ) for ( emailcategory_ ) in (
    'Email1' as "Email1"  -- optional: use AS ... here to "beautify" the column headings
  , 'Email2' as "Email2"
  , 'Email3'
  , 'Email4' 
  )
) ;

DBfiddle ici .


0 commentaires