Oracle 11g SQL:数据透视表 - 可变列数

时间:2014-05-30 20:02:00

标签: sql oracle oracle11g pivot

我正在尝试获取一个表并将两列的值转换为它们自己的列。扭曲是每个锚可以有可变数量的条目。这是一张玩具桌:

    CREATE TABLE ATTRS
    ( WIDGET VARCHAR2(15), 
      A_NAME VARCHAR2(15), 
      A_VALUE VARCHAR2(15)
     );
    INSERT INTO ATTRS VALUES ('BOOK','PAGES','1000');
    INSERT INTO ATTRS VALUES ('BOOK','COLOR','GREEN');
    INSERT INTO ATTRS VALUES ('BOOK','LAST','TWAIN');
    INSERT INTO ATTRS VALUES ('BOOK','FIRST','MARK');
    INSERT INTO ATTRS VALUES ('CELLPHONE','BRAND','SAMSUNG');
    INSERT INTO ATTRS VALUES ('LAPTOP','BRAND','LENOVO');
    INSERT INTO ATTRS VALUES ('LAPTOP','COLOR','BLACK');
    INSERT INTO ATTRS VALUES ('LAPTOP','BATTERY','STANDARD');

我将知道可能出现的唯一A_NAME的最大数量(在此示例中我们将其设为4)并希望输出如下:

    WIDGET    | A_NAME1 | A_VALUE1 | A_NAME2 | A_VALUE2 | A_NAME3 | A_VALUE3   | A_NAME4 | A_VALUE4
    ------------------------------------------------------------------------------------------
    BOOK      | PAGES   | '1000'   | COLOR   | 'GREEN'  | LAST    | 'TWAIN'    | FIRST   | 'MARK'
    CELLPHONE | BRAND   | 'SAMSUNG'| (null)  | (null)   | (null)  | (null)     | (null)  | (null) 
    LAPTOP    | COLOR   | 'BLACK'  | BRAND   | 'LENOVO' | BATTERY | 'STANDARD' | (null)  | (null) 

请注意,订单无关紧要,即如果两个A_NAME相同,则需要在同一列中。

感谢。

1 个答案:

答案 0 :(得分:0)

我必须考虑一下如何使用新的(在11g)pivot运算符中完成此操作。但是,知道每widget最多有4行,你可以按照

的方式进行旧学校的调整。
SELECT widget,
       max(CASE WHEN rn = 1 THEN a_name ELSE NULL END) a_name1,
       max(CASE WHEN rn = 1 THEN a_value ELSE NULL END) a_value1,
       max(CASE WHEN rn = 2 THEN a_name ELSE NULL END) a_name2,
       max(CASE WHEN rn = 2 THEN a_value ELSE NULL END) a_value2,
       max(CASE WHEN rn = 3 THEN a_name ELSE NULL END) a_name3,
       max(CASE WHEN rn = 3 THEN a_value ELSE NULL END) a_value3,
       max(CASE WHEN rn = 4 THEN a_name ELSE NULL END) a_name4,
       max(CASE WHEN rn = 4 THEN a_value ELSE NULL END) a_value4
  FROM( SELECT widget,
               a_name,
               a_value,
               row_number() over (partition by widget 
                                      order by a_name, a_value) rn
          FROM attrs )
 GROUP BY widget