在游标中打印数据(将行转置为列)

时间:2014-03-03 12:33:08

标签: oracle cursor transpose

我在游标中有来自查询的数据,如下所示:

parent   child   month   qty
a          b      jan     2
a          b      feb     3
a          b      mac     1

我想要打印数据:

parent child jan feb mac
a        b    2   3   1

如何使用循环打印?我在我的查询中尝试使用数据透视表,但是月份列是动态的,我以后无法显示它。 有人可以帮忙吗?

2 个答案:

答案 0 :(得分:0)

select parent, child, JAN, FEB, MAR, qty
from 
(
select parent, child, month JAN, NULL FEB, NULL MAR, qty
from yourtablename
where month = 'JAN'
and parent = 'a'
and child  = 'b'

UNION ALL

select parent, child, NULL JAN, MONTH FEB, NULL MAR, qty
from yourtablename
where month = 'FEB'
and parent = 'a'
and child  = 'b'


UNION ALL

select parent, child, NULL JAN, NULL FEB, MONTH MAR, qty
from yourtablename
where month = 'MAR'
and parent = 'a'
and child  = 'b'

)

答案 1 :(得分:0)

简单SQL解决方案

WITH YOURTABLE AS
(
  SELECT 'a' AS PARENT,'b' AS CHILD,'JAN' AS MONTH,2 AS QUANTITY FROM DUAL
  UNION ALL
  SELECT 'a','b','FEB',3 FROM DUAL
  UNION ALL
  SELECT 'a','b','MAR',1 FROM DUAL
  UNION ALL
  SELECT 'a','c','JAN',5 FROM DUAL
  UNION ALL
  SELECT 'a','c','FEB',6 FROM DUAL
  UNION ALL
  SELECT 'a','c','MAR',3 FROM DUAL
)
SELECT
   PARENT,
   CHILD,
   MAX(DECODE( MONTH,'JAN',QUANTITY,0)) AS JAN,
   MAX(DECODE( MONTH,'FEB',QUANTITY,0)) AS FEB,
   MAX(DECODE( MONTH,'MAR',QUANTITY,0)) AS MAR,
   MAX(DECODE( MONTH,'APR',QUANTITY,0)) AS APR,
   MAX(DECODE( MONTH,'MAY',QUANTITY,0)) AS MAY,
   MAX(DECODE( MONTH,'JUN',QUANTITY,0)) AS JUN,
   MAX(DECODE( MONTH,'JUL',QUANTITY,0)) AS JUL,
   MAX(DECODE( MONTH,'AUG',QUANTITY,0)) AS AUG,
   MAX(DECODE( MONTH,'SEP',QUANTITY,0)) AS SEP,
   MAX(DECODE( MONTH,'OCT',QUANTITY,0)) AS OCT,
   MAX(DECODE( MONTH,'NOV',QUANTITY,0)) AS NOV,
   MAX(DECODE( MONTH,'DEC',QUANTITY,0)) AS DEC
FROM
  YOURTABLE
GROUP BY PARENT,CHILD

DEMO: SQL Fiddle


Bit Complex PL / SQL解决方案:

结果必须按PARENT,CHILD

排序
DECLARE
  CURSOR MYCUR
  IS
    SELECT 'a' AS PARENT,'b' AS CHILD,'JAN' AS MONTH,2 AS QUANTITY FROM DUAL
  UNION ALL
  SELECT 'a','b','FEB',3 FROM DUAL
  UNION ALL
  SELECT 'a','b','MAR',1 FROM DUAL
  UNION ALL
  SELECT 'a','c','JAN',5 FROM DUAL
  UNION ALL
  SELECT 'a','c','FEB',6 FROM DUAL
  UNION ALL
  SELECT 'a','c','MAR',3 FROM DUAL;
  v_MYTYPE MYCUR%ROWTYPE;
  v_prev_child VARCHAR2(100);
  ROWSTR       VARCHAR2(4000);
  TYPE MONTHS IS TABLE OF VARCHAR2(10) INDEX BY VARCHAR2(30);
  v_MONTHS MONTHS;
BEGIN
  /* Create a associative array of months initialised with quantiy 0 */

  FOR REC IN (SELECT TO_CHAR(ADD_MONTHS(TRUNC(sysdate,'YYYY'),level-1),'MON') AS MONTH_NAME
              FROM DUAL
              CONNECT BY LEVEL <= 12)
  LOOP
       v_MONTHS(REC.MONTH_NAME) := 0;
  END LOOP;

  FOR REC IN MYCUR
  LOOP
    IF(v_prev_child   IS NULL) THEN
      v_prev_child    := REC.CHILD;
      ROWSTR          := REC.PARENT||' '||REC.CHILD;
      v_MONTHS(REC.MONTH) := REC.QUANTITY;
    ELSIF(v_prev_child = REC.CHILD) THEN
      v_MONTHS(REC.MONTH) := REC.QUANTITY;
    ELSE
      FOR REC IN (SELECT TO_CHAR(ADD_MONTHS(TRUNC(sysdate,'YYYY'),level-1),'MON') AS MONTH_NAME
                  FROM DUAL
                 CONNECT BY LEVEL <= 12)
      LOOP
          ROWSTR := ROWSTR||' '||v_MONTHS(REC.MONTH_NAME);
          v_MONTHS(REC.MONTH_NAME) := 0; /* Initialse to 0 again*/
      END LOOP;
      DBMS_OUTPUT.PUT_LINE(ROWSTR);

      v_prev_child    := REC.CHILD;
      ROWSTR          := REC.PARENT||' '||REC.CHILD;
      v_MONTHS(REC.MONTH) := REC.QUANTITY;
    END IF;
  END LOOP;
  FOR REC IN (SELECT TO_CHAR(ADD_MONTHS(TRUNC(sysdate,'YYYY'),level-1),'MON') AS MONTH_NAME
              FROM DUAL
             CONNECT BY LEVEL <= 12)
  LOOP
      ROWSTR := ROWSTR||' '||v_MONTHS(REC.MONTH_NAME);
      v_MONTHS(REC.MONTH_NAME) := 0; /* Initialse to 0 again*/
  END LOOP;
  /* Last Row */
  DBMS_OUTPUT.PUT_LINE(ROWSTR);
END;
/