如何查询,一对多关系,非规范化

时间:2016-05-19 20:12:54

标签: sql oracle

我对标题感到抱歉,我不知道该怎么问。我有表,实体和电子邮件,这是一对多的关系。

我的代码是

select e.pref_mail_name, em.email_address
from entity e
left join email em ON em.id_number = e.id_number

然后输出就像这样

pref_mail_name   --------------- em.email_address
jsmith                           jsmith@yahoo.com
El Alex                          EL@yahoo.com
EL ALex                          EL@Gmail.com
EL Alex                          EL@hotmail.com
Jay smith                        Jsm@gmail.com

我想像这样展示

  pref_mail_name ----em.email_address1---em.email_address2--em.email_address3
  jsmith             jsmith@yahoo.com
  El Alex            EL@yahoo.com        EL@Gmail.com      EL@hotmail.com 
  Jay smith          Jsm@gmail.com

如何编写一个如上所述的回显信息?

2 个答案:

答案 0 :(得分:1)

如果您只想要静态列,可以使用以下方法,它利用了lead函数(您也可以使用lag并反转排序):

select e.pref_mail_name, em.email_address1, em.email_address2, em.email_address3
from entity e
left join (
    select 
      id_number,
      rank() over (partition by id_number order by email_address asc) as email_rank,
      lead(email_address,0,null) over (partition by id_number order by id_number, email_address asc) as email_address1,
      lead(email_address,1,null) over (partition by id_number order by id_number, email_address asc) as email_address2,
      lead(email_address,2,null) over (partition by id_number order by id_number, email_address asc) as email_address3
    from email
 ) em 
    ON em.id_number = e.id_number
    AND em.email_rank = 1

答案 1 :(得分:0)

SELECT 
  e.pref_mail_name
  ,max(case when rn=1 then email_address end) email_1
  ,max(case when rn=2 then email_address end) email_2
  ,max(case when rn=3 then email_address end) email_3
FROM entity e LEFT JOIN 
  (select email_address, id_number
          ,row_number() over (partition by id_number order by 2) rn from email) em
ON (e.id_number=em.id_number)
GROUP by pref_mail_name, 2;