微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用Oracle11g将多行连接为一行而不进行聚合

如何解决使用Oracle11g将多行连接为一行而不进行聚合

下面的链接显示了与我想问的问题相同的问题以及为回答该查询而提供的代码,我使用了此查询(对它进行了修改),但是请问如何添加联接表和where子句在这查询中?请参阅下面的代码,我已将其添加到下面的链接中的代码中,但是却收到错误消息。我希望输出与以下链接中提供的输出相同

Joining multiple rows into a single row without aggregation [Oracle]

请记住,链接中提供的预期结果与我的预期结果相同。

下面是我修改过的脚本:

select max(case when seqnum = 1 then p.PERSONID end) as PersonID,max(case when seqnum = 1 then t.PHONEID end) as PhoneID1,max(case when seqnum = 1 then t.PHONENUM end) as PhoneNum1,max(case when seqnum = 1 then t.TYPE end) as Type1,max(case when seqnum = 1 then t.ISPRIMARY end) as IsPrimary1,max(case when seqnum = 1 then t.ROWSTAMP1 end) as Rowstamp1,max(case when seqnum = 2 then t.PHONEID end) as PhoneID2,max(case when seqnum = 2 then t.PHONENUM end) as PhoneNum2,max(case when seqnum = 2 then t.TYPE end) as Type2,max(case when seqnum = 2 then t.ISPRIMARY end) as IsPrimary2,max(case when seqnum = 2 then t.ROWSTAMP1 end) as Rowstamp2,max(case when seqnum = 3 then t.PHONEID end) as PhoneID3,max(case when seqnum = 3 then t.PHONENUM end) as PhoneNum3,max(case when seqnum = 3 then t.TYPE end) as Type3,max(case when seqnum = 3 then t.ISPRIMARY end) as IsPrimary3,max(case when seqnum = 3 then t.ROWSTAMP1 end) as Rowstamp3
      from (test1.phone t left join test2.person p  
            ON t1.PERSONID = t2.PERSONID
      where t2.PERSONID = 'MXSDFD'
      ) t;
      rownum as seqnum
      from t
    

解决方法

使用PIVOT

select personid,"1_PHONEID"   AS phoneid1,"1_PHONENUM"  AS phonenum1,"1_TYPE"      AS type1,"1_ISPRIMARY" AS isprimary1,"1_ROWSTAMP1" AS rowstamp1,"2_PHONEID"   AS phoneid2,"2_PHONENUM"  AS phonenum2,"2_TYPE"      AS type2,"2_ISPRIMARY" AS isprimary2,"2_ROWSTAMP1" AS rowstamp2,"3_PHONEID"   AS phoneid3,"3_PHONENUM"  AS phonenum3,"3_TYPE"      AS type3,"3_ISPRIMARY" AS isprimary3,"3_ROWSTAMP1" AS rowstamp3
from   (
  SELECT p.personid,t.phoneid,t.phonenum,t.type,t.isprimary,t.rowstamp1,ROW_NUMBER() OVER (
           PARTITION BY p.personid ORDER BY t.isprimary DESC,t.rowstamp1 DESC
         ) AS seqnum
  FROM   person p
         left join phone t   
         ON ( t.PERSONID = p.PERSONID )
  where  t.PERSONID = 'MXSDFD'
)
PIVOT (
  MAX( phoneid ) AS phoneid,MAX( phonenum ) AS phonenum,MAX( type ) AS type,MAX( isprimary ) AS isprimary,MAX( rowstamp1 ) AS rowstamp1
  FOR seqnum IN ( 1,2,3 )
)

其中的示例数据:

CREATE TABLE person ( personid,name ) AS
SELECT 'MXSDFD','Alice' FROM DUAL;

CREATE TABLE phone ( personid,phonenum,phoneid,type,isprimary,rowstamp1 ) AS
SELECT 'MXSDFD','012346',1,'A','N',TIMESTAMP '2020-10-13 09:00:00' FROM DUAL UNION ALL
SELECT 'MXSDFD','555666',3,'C',TIMESTAMP '2020-10-13 08:30:00' FROM DUAL UNION ALL
SELECT 'MXSDFD','987654','B','Y',TIMESTAMP '2020-10-13 08:00:00' FROM DUAL;

输出:

PERSONID | PHONEID1 | PHONENUM1 | TYPE1 | ISPRIMARY1 | ROWSTAMP1                    | PHONEID2 | PHONENUM2 | TYPE2 | ISPRIMARY2 | ROWSTAMP2                    | PHONEID3 | PHONENUM3 | TYPE3 | ISPRIMARY3 | ROWSTAMP3                   
:------- | -------: | :-------- | :---- | :--------- | :--------------------------- | -------: | :-------- | :---- | :--------- | :--------------------------- | -------: | :-------- | :---- | :--------- | :---------------------------
MXSDFD   |        2 | 987654    | B     | Y          | 13-OCT-20 08.00.00.000000000 |        1 | 012346    | A     | N          | 13-OCT-20 09.00.00.000000000 |        3 | 555666    | C     | N          | 13-OCT-20 08.30.00.000000000

db 提琴here

,

您似乎想要这样的逻辑:

select max(case when seqnum = 1 then t.PERSONID end) as PersonID,max(case when seqnum = 1 then t.PHONEID end) as PhoneID1,max(case when seqnum = 1 then t.PHONENUM end) as PhoneNum1,max(case when seqnum = 1 then t.TYPE end) as Type1,max(case when seqnum = 1 then t.ISPRIMARY end) as IsPrimary1,max(case when seqnum = 1 then t.ROWSTAMP1 end) as Rowstamp1,max(case when seqnum = 2 then t.PHONEID end) as PhoneID2,max(case when seqnum = 2 then t.PHONENUM end) as PhoneNum2,max(case when seqnum = 2 then t.TYPE end) as Type2,max(case when seqnum = 2 then t.ISPRIMARY end) as IsPrimary2,max(case when seqnum = 2 then t.ROWSTAMP1 end) as Rowstamp2,max(case when seqnum = 3 then t.PHONEID end) as PhoneID3,max(case when seqnum = 3 then t.PHONENUM end) as PhoneNum3,max(case when seqnum = 3 then t.TYPE end) as Type3,max(case when seqnum = 3 then t.ISPRIMARY end) as IsPrimary3,max(case when seqnum = 3 then t.ROWSTAMP1 end) as Rowstamp3
from (select t.*,rownum as seqnum
      from test1.phone t join
           test2.person p  
           on t.PERSONID = p.PERSONID
      where p.PERSONID = 'MXSDFD'
     ) t;

也就是说,您似乎根本不需要join,因为您正在过滤联接键(两个表中都有)。所以:

from (select t.*,rownum as seqnum
      from test1.phone t 
      where t.PERSONID = 'MXSDFD'
     ) t

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。