Oracle将DECODE转换为PIVOT或强制使用索引

时间:2013-06-11 11:47:34

标签: oracle indexing oracle11g pivot decode

我有一个非常复杂的SQL视图定义,它已被继承并需要更改以提高性能。它采用基于外键的记录列表,并显示作为列返回的行。

因此: - 来自select的数据使用RANK

ID RANK DKEY RECORD1 RECORD2 RECORD3
1  1    1    003     Rob     Emmerry
1  2    2    004     Sue     Emmerry

返回

ID REC11 REC12 REC13   REC21 REC22 REC23
1  003   Rob   Emmerry 004   Sue   Emmerry

每个返回的行重复有37列数据,最多5个。 使用

SELECT ID,
MIN(DECODE(ranking,1,RECORD1, NULL)) AS REC11
MIN(DECODE(ranking,1,RECORD2, NULL)) AS REC12
MIN(DECODE(ranking,1,RECORD3, NULL)) AS REC13
MIN(DECODE(ranking,1,RECORD4, NULL)) AS REC14
MIN(DECODE(ranking,1,RECORD5, NULL)) AS REC15
MIN(DECODE(ranking,1,RECORD6, NULL)) AS REC16
MIN(DECODE(ranking,2,RECORD1, NULL)) AS REC21
MIN(DECODE(ranking,2,RECORD2, NULL)) AS REC22
MIN(DECODE(ranking,2,RECORD3, NULL)) AS REC23
MIN(DECODE(ranking,2,RECORD4, NULL)) AS REC24
MIN(DECODE(ranking,2,RECORD5, NULL)) AS REC25
MIN(DECODE(ranking,2,RECORD6, NULL)) AS REC26
FROM 
(
SELECT ID, RANK () OVER (PARTITION BY id ORDER BY dkey) ranking,
RECORD1,
RECORD2,
RECORD3,
RECORD4,
RECORD5,
RECORD6
FROM TABLEA
JOIN
 (SELECT ID, DKEY, RECORD4, RECORD5, RECORD6
  FROM TABLEB
 ) ON TABLEB.DKEY = TABLEA.DKEY AND TABLEB.ID = TABLEA.ID
)
GROUP BY ID;

当使用解释计划并对具有索引的DKEY字段进行过滤时,可能会因为min / decode语句而忽略索引。

所以我想过用PIVOT重写它,但不知道如何开始。

关于我怎么做的任何想法 a)获取查询以使用索引 b)使用PIVOT重写

第一种选择显然更可取。

由于 克雷格

更新

以下是一些示例数据,显示了我的表格。

    Table 1             
    DKEY PID RECORD1 RECORD2 RECORD3
    1    1   3       Rob     Emmerry
    2    1   4       Sue     Emmerry
    3    1   4       Jan     Morris
    4    1   4       Sue     Pye
    5    1   4       Jane    Taylor

    Table 2             
    CID DKEY RECORD10       
    1   3    A      
    2   3    D      
    3   3    G      
    4   3    J      
    5   4    A      
    6   5    A      
    7   5    D      
    8   6    A      
    9   6    D      
    10  6    G      
    11  7    A      
    12  7    D      
    13  7    G      
    14  7    J      
    15  7    M      

    Table 3             
    QID DKEY RECORD3        
    1   3    C      
    2   6    C      
    3   6    F      
    4   7    C      
    5   7    F      

所以表2& 3链接到表1与DKEY 如果我们以DKEY = 3为例,我希望看到: -

    PID DKEY REC1 REC2 REC3   REC4 REC5 REC6 REC7 REC8 REC9 REC10 REC11 REC12 REC13
    1   3    4    Jan  Morris A    D    G    J    NULL C    NULL  NULL  NULL  NULL

每个表格2和表格中最多可以有5行。 3.表1中的字段PID,DKEY,REC1-REC3,REC4-REC8来自表2,其余来自表3.表1中的其他记录将继续在该行上,因此在REC13,DKEY = 4等之后。

希望这是有道理的。

1 个答案:

答案 0 :(得分:0)

SELECT
    ID,
    MIN(DECODE(ranking,1,RECORD1, NULL)) AS REC11,
    MIN(DECODE(ranking,1,RECORD2, NULL)) AS REC12,
    MIN(DECODE(ranking,1,RECORD3, NULL)) AS REC13,
    MIN(DECODE(ranking,1,RECORD4, NULL)) AS REC14,
    MIN(DECODE(ranking,1,RECORD5, NULL)) AS REC15,
    MIN(DECODE(ranking,1,RECORD6, NULL)) AS REC16,
    MIN(DECODE(ranking,2,RECORD1, NULL)) AS REC21,
    MIN(DECODE(ranking,2,RECORD2, NULL)) AS REC22,
    MIN(DECODE(ranking,2,RECORD3, NULL)) AS REC23,
    MIN(DECODE(ranking,2,RECORD4, NULL)) AS REC24,
    MIN(DECODE(ranking,2,RECORD5, NULL)) AS REC25,
    MIN(DECODE(ranking,2,RECORD6, NULL)) AS REC26
FROM 
(
    SELECT /*+ INDEX(tablea tablea_index) */
        ID,
        RANK () OVER (PARTITION BY id ORDER BY dkey) ranking,
        RECORD1,
        RECORD2,
        RECORD3,
        RECORD4,
        RECORD5,
        RECORD6
    FROM TABLEA
    JOIN TABLEB
    -- was: ON TABB.DKEY = TABLEA.DKEY AND TABB ON TABB.ID = TABLEA.ID
    ON  TABLEB.DKEY = TABLEA.DKEY
    AND TABLEB.ID   = TABLEA.ID
)
GROUP BY ID;