使用unpivot

时间:2018-06-18 18:04:45

标签: oracle11g unpivot dml dblink

因此,我们的组织中有一个用于安排并从中报告数据的表。计划行包含一周中每一天的列,其值为' Y'或者' N'取决于当天是否有会议。我已经设法使用UNPIVOT在一个简单的选择中做到这一点,但不幸的是,我们的需求比这更复杂。

我需要通过DB_Link上的远程表上的调度表中的查询插入到本地表中,该调用是不透明的,例如:

SELECT *
FROM   (SELECT class_nbr,
               TERM,
               MON,
               TUES,
               WED,
               THURS,
               FRI,
               SAT,
               SUN
         FROM  schedule_tbl) sched 
UNPIVOT (wkDay FOR DayWeek IN (MON, TUES, WED, THURS, FRI, SAT, SUN)) piv
WHERE   piv.WkDay = 'Y'

再一次,当我在Sql Developer中针对schedule_tbl所在的服务器运行它时,这很好。我得到了像

这样的结果
Class_nbr TERM DayWeek
1234      Fall MON
1234      Fall Wed
....

然而,令人惊讶的是,当我尝试从不同的服务器插入此结果时,如

INSERT INTO other_table (class_nbr, TERM, DayWeek)
SELECT *
FROM   (SELECT class_nbr,
               TERM,
               MON,
               TUES,
               WED,
               THURS,
               FRI,
               SAT,
               SUN
         FROM  schedule_tbl@db_link) sched 
UNPIVOT (wkDay FOR DayWeek IN (MON, TUES, WED, THURS, FRI, SAT, SUN)) piv
WHERE   piv.WkDay = 'Y'

会发生的事情是只有DayWeek =' MON'插入。应该插入的星期一行的实际数量是。我不知道这是怎么回事。如果我更改UNPIVOT列的顺序,使TUES成为第一个,那么只插入星期二行(再次,正确的数字)。

编辑:我想我可以在这里分享我的实际代码。请记住,如果我将这个确切的查询带到远程数据库并删除dblinks,我得到的不仅仅是星期一行:

SELECT  '%processinstance',
    0 ,
    crse_id ,
    crse_offer_nbr ,
    strm ,
    session_code ,
    class_section ,
    subject ,
    institution ,
    facility_id ,
    ' ' ,
    ' ' ,
    '0001484' ,
    '4' ,
    PDB_DE0120_TRM_ID ,
    subject || catalog_nbr ,
    strm || class_nbr ,
    to_char ( start_dt , 'YYYYMMDD' ) ,
    to_char ( end_dt , 'YYYYMMDD' ) ,
    DECODE(DAYWEEK,'MON', 'M', 'TUES','T', 'WED','W', 'THURS','R', 'FRI','F', 'SAT','S', 'SUN','X'),
    nvl ( to_char ( meeting_time_start ,'HH24MI' ) ,'9999' ) ,
    nvl ( to_char ( meeting_time_end ,'HH24MI' ) ,'9999' ) ,
    ' ' ,
    ' ' ,
    ' ' ,
    0 ,
    'S' ,
    'C' ,
    decode ( instruction_mode ,'HB' ,'X' ,'DL' ,'X' ,'N' ) ,
    ' ' ,
    ' ' ,
    ' ' ,
    ' ' ,
    ' ' ,
    'E' ,
    SYSDATE ,
    ' ' ,
    SYSDATE,
    ' ' ,
    ' '
FROM    (SELECT A.crse_id ,
                A.crse_offer_nbr ,
                A.strm ,
                A.session_code ,
                A.class_section ,
                B.institution ,
                A.facility_id ,
                B.instruction_mode,
                B.SUBJECT,
                B.CATALOG_NBR,
                A.meeting_time_start,
                A.meeting_time_end,
                B.START_DT,
                B.END_DT,
                B.CLASS_NBR,
                C.PDB_DE0120_TRM_ID,
                MON, 
                TUES, 
                WED, 
                THURS,
                FRI,
                SAT,
                SUN
        FROM    PS_CLASS_MTG_PAT@CSDV1 A
                INNER JOIN  PS_CLASS_TBL@CSDV1 B
                ON          A.STRM = B.STRM AND
                            A.CRSE_ID = B.CRSE_ID AND
                            A.CLASS_SECTION = B.CLASS_SECTION
                INNER JOIN  PS_FSC_SRPT_TRM_VW@CSDV1 C
                ON          C.STRM = B.STRM AND
                            C.ACAD_CAREER = 'CRED'
        WHERE   A.STRM = '2182' AND
                (B.CLASS_STAT <> 'X' OR
                (B.ENRL_TOT > 0 AND
                B.ENRL_STAT <> 'C')) AND
                B.acad_group NOT IN ( '11','12','13','23','80','99' )) B
UNPIVOT EXCLUDE NULLS (wkDay FOR DayWeek IN ( MON AS 'MON', TUES AS 'TUES', WED AS 'WED', THURS AS 'THURS', FRI AS 'FRI', SAT AS 'SAT', SUN AS 'SUN')) piv
WHERE   piv.wkDay = 'Y';

第二次更新:根据要求,我正在粘贴更正的查询:

SELECT  '%processinstance',
    0 ,
    crse_id ,
    crse_offer_nbr ,
    strm ,
    session_code ,
    class_section ,
    subject ,
    institution ,
    facility_id ,
    ' ' ,
    ' ' ,
    '0001484' ,
    '4' ,
    PDB_DE0120_TRM_ID ,
    subject || catalog_nbr ,
    strm || class_nbr ,
    to_char ( start_dt , 'YYYYMMDD' ) ,
    to_char ( end_dt , 'YYYYMMDD' ) ,
    DECODE(DAYWEEK,'MON', 'M', 'TUES','T', 'WED','W', 'THURS','R', 'FRI','F', 'SAT','S', 'SUN','X'),
    nvl ( to_char ( meeting_time_start ,'HH24MI' ) ,'9999' ) ,
    nvl ( to_char ( meeting_time_end ,'HH24MI' ) ,'9999' ) ,
    ' ' ,
    ' ' ,
    ' ' ,
    0 ,
    'S' ,
    'C' ,
    decode ( instruction_mode ,'HB' ,'X' ,'DL' ,'X' ,'N' ) ,
    ' ' ,
    ' ' ,
    ' ' ,
    ' ' ,
    ' ' ,
    'E' ,
    ' ' ,
    ' ' ,
    ' '
FROM    (SELECT A.crse_id ,
                A.crse_offer_nbr ,
                A.strm ,
                A.session_code ,
                A.class_section ,
                B.institution ,
                A.facility_id ,
                B.instruction_mode,
                B.SUBJECT,
                B.CATALOG_NBR,
                A.meeting_time_start,
                A.meeting_time_end,
                B.START_DT,
                B.END_DT,
                B.CLASS_NBR,
                C.PDB_DE0120_TRM_ID,
                MON, 
                TUES, 
                WED, 
                THURS,
                FRI,
                SAT,
                SUN
        FROM    PS_CLASS_MTG_PAT@CSDV1 A
                INNER JOIN  PS_CLASS_TBL@CSDV1 B
                ON          A.STRM = B.STRM AND
                            A.CRSE_ID = B.CRSE_ID AND
                            A.CLASS_SECTION = B.CLASS_SECTION
                INNER JOIN  PS_FSC_SRPT_TRM_VW@CSDV1 C
                ON          C.STRM = B.STRM AND
                            C.ACAD_CAREER = 'CRED'
        WHERE   A.STRM = '2182' AND
                (B.CLASS_STAT <> 'X' OR
                (B.ENRL_TOT > 0 AND
                B.ENRL_STAT <> 'C')) AND
                B.acad_group NOT IN ( '11','12','13','23','80','99' )) B
UNPIVOT EXCLUDE NULLS (wkDay FOR DayWeek IN ( MON AS 'MON', TUES AS 'TUES', WED AS 'WED', THURS AS 'THURS', FRI AS 'FRI', SAT AS 'SAT', SUN AS 'SUN')) piv
WHERE   piv.wkDay = 'Y';

1 个答案:

答案 0 :(得分:0)

这不是一个完全令人满意的解决方案,但是它对我有用。如果我从我的select子句( any 两列)中删除了两个表达式,此问题将消失。显然,这是以前涉及DB Links的Oracle问题,好像我进行了相同的查询并在存在表的远程服务器上运行它一样,并且在Oracle文档中没有关于DB Links的内容。我会在某个时候尝试与他们一起提高它。