如何在Oracle SQL中动态显示列中的行数据

时间:2016-01-21 11:16:55

标签: sql oracle pivot

我在Oracle中有以下格式的表数据:

Roll_No Paper Code    Inst_Code
1       71            10
1       72            10
1       73            10
2       71            10
2       73            10
2       75            10
3       72            11
3       73            11
4       71            11
4       73            11

等等。 我想动态地以下列格式显示数据......

Inst_Code    71     72      73     75
--------     ---    ---     ---    ---
10           2      1       2      1
11           1      1       2      0

3 个答案:

答案 0 :(得分:3)

with t(Roll_No,
Paper_Code,
Inst_Code) as
 (          select 1, 71, 10 from dual
  union all select 1, 72, 10 from dual
  union all select 1, 73, 10 from dual
  union all select 2, 71, 10 from dual
  union all select 2, 73, 10 from dual
  union all select 2, 75, 10 from dual
  union all select 3, 72, 11 from dual
  union all select 3, 73, 11 from dual
  union all select 4, 71, 11 from dual
  union all select 4, 73, 11 from dual)

select *
  from (select paper_code, inst_code, count(*) total
          from t
         group by paper_code, inst_code) pivot(sum(total) for paper_code in(71,
                                                                            72,
                                                                            73,
                                                                            75));

答案 1 :(得分:1)

我不相信你可以构建一个SQL,只要你有一个或多个可变数字。我能找到的最好的是一些构建查询的动态SQL:

set serveroutput on
DECLARE
    vSQL              VARCHAR2(1000) :=
     'SELECT *
      FROM   (SELECT paper_code, inst_node
              FROM   test)
      PIVOT  (count(1)  FOR (paper_code) IN (PaperCodeList))
      order by inst_node';
    vPaperCodeList    VARCHAR2(1000);
BEGIN
    SELECT LISTAGG(paper_code || ' as "' || paper_code ||'"', ', ')  WITHIN GROUP (ORDER BY paper_code)  as list
      INTO vPaperCodeList
      FROM (SELECT DISTINCT paper_code FROM test);

    vSQL      := REPLACE(
                         vSQL,
                         'PaperCodeList',
                         vPaperCodeList
                        );
    dbms_output.put_line(vSQL);
END;
/  

这将构建如下的查询:

SQL> SELECT *
  2        FROM   (SELECT paper_code, inst_node
  3                FROM   test)
  4        PIVOT  (count(1)  FOR (paper_code) IN (71 as "71", 72 as "72", 73 as "73", 75 as "75"))
  5        order by inst_node;

 INST_NODE         71         72         73         75
---------- ---------- ---------- ---------- ----------
        10          2          1          2          1
        11          1          1          2          0  

答案 2 :(得分:0)

弗兰克斯回答不会使用动态列表列表,因为您需要声明所有列,因此它们的数量不会发生变化。动态构建SQL的另一个选择是使用XML(它可以在任何&#34中使用"):

SELECT *
     FROM (
            SELECT Roll_No,
                 Paper_Code,
                 Inst_Code
            FROM t
            )
            PIVOT XML(COUNT(Roll_No) AS "Value" FOR paper_code IN (ANY))

这样输出将是2列:inst_code和paper_code_xml,其中包含所有paper_counts及其值:

 INST_CODE PAPER_CODE_XML
 10 <XMLTYPE>
 11 <XMLTYPE>

其中xml值为:

<PivotSet>
<item>
    <column name = "PAPER_CODE">71</column>
    <column name = "Value">2</column>
</item>
<item>
    <column name = "PAPER_CODE">72</column>
    <column name = "Value">1</column>
</item>
<item>
    <column name = "PAPER_CODE">73</column>
    <column name = "Value">2</column>
</item>
<item>
    <column name = "PAPER_CODE">75</column>
    <column name = "Value">1</column>
</item>