Sql Pivot:垂直显示字段

Posted

技术标签:

【中文标题】Sql Pivot:垂直显示字段【英文标题】:Sql Pivot: Display fields vertically 【发布时间】:2020-06-22 18:44:21 【问题描述】:

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

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 列下的值将为空。我知道我很接近,但我不确定如何让它为多个学生工作并停止使用 rownum。 对此的任何帮助将不胜感激。提前致谢

【问题讨论】:

【参考方案1】:

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

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;

【讨论】:

您好,我认为这效果最好。它确实以垂直方式发送电子邮件。我一直在尝试操纵查询以包括电子邮件类型。每个电子邮件地址都有一个电子邮件类型。所以它会像 @user1898629 。 . .只需使用type 而不是email 添加带有max() 的附加列。 感谢您在此问题上的帮助。我能够生产我需要的东西【参考方案2】:

如果您不关心(因为这样的东西无法扩展),请考虑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>

【讨论】:

【参考方案3】:

您可以生成您的电子邮件类别(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' 
  )
) ;

DBfiddle here.

【讨论】:

以上是关于Sql Pivot:垂直显示字段的主要内容,如果未能解决你的问题,请参考以下文章

如何在sql中垂直而不是水平显示字段

SQL Pivot - 查询结果垂直到水平

Sql 动态行转列 pivot

如何在不使用pivot和unpivot的情况下在SQL Server中水平显示数据?

在 ms sql 中旋转 2 列并依次显示数据

sql查询结果横向显示?