sql透视:垂直显示字段

quhf5bfb  于 2021-07-24  发布在  Java
关注(0)|答案(3)|浏览(275)

我试图创建一个查询,其中数据基本上是水平显示的,而不是垂直显示的。我相信它被称为旋转(我对这个有点陌生)。考虑以下情况:我可以查询一个学生的地址,他们会这样显示

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

我宁愿数据水平显示,如

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

我已经完成了以下一个人的问题。

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

这对一个人有效,主要是因为我使用rownum。在本例中,列entry4下的值将为null。我知道我很接近,但我不知道如何让它为多个学生工作,并停止使用rownum。在此方面的任何帮助都将不胜感激。提前谢谢

ivqmmu1c

ivqmmu1c1#

如果需要三个,可以使用条件聚合

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;
xzlaal3s

xzlaal3s2#

如果您不关心列(因为这样的东西不能缩放),请考虑 listagg 它允许您“串联”多达4000个字符的电子邮件地址。
例如(请注意,#1-10行表示样本数据;您的表中已经有了它,因此您可能需要考虑的查询从第11行开始):

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>

或者,稍微漂亮一点 rpad ):

<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>
8wtpewkr

8wtpewkr3#

您可以生成电子邮件类别(email1、email2等),然后在pivot子句中使用它们。不过,请确保在pivot中编写了足够多的类别(例如,当使用以下查询时:如果某人有5个电子邮件地址,则其中一个地址将不在结果集中。)

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' 
  )
) ;

在这儿摆弄。

相关问题