【DB筆試面試467】Oracle中行列互換有哪些方法?

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

         題目         部分

Oracle中行列互換有哪些方法?程序員


     
         答案部分          


行列轉換包括如下六種狀況:(1)列轉行。(2)行轉列。(3)多列轉換成字符串。(4)多行轉換成字符串。(5)字符串轉換成多列。(6)字符串轉換成多行。其中,重點是行轉列和字符串轉換成多行。面試

下面將分別對這幾種狀況舉例來講明。數據庫

1、列轉行微信

列轉行就是將原表中的列名做爲轉換後的表的內容。列轉行主要採用UNION ALL來完成。示例代碼以下所示網絡

CREATE TABLE TEST_LHRapp

(ide

  NAME     VARCHAR2(255),函數

  JANUARY  NUMBER(18),學習

  FEBRUARY NUMBER(18),測試

  MARCH    NUMBER(18),

  APRIL    NUMBER(18),

  MAY      NUMBER(18)

);

INSERT INTO TEST_LHR (NAME, JANUARY, FEBRUARY, MARCH, APRIL, MAY)

VALUES ('長壽', 58, 12, 26, 18, 269);

INSERT INTO TEST_LHR (NAME, JANUARY, FEBRUARY, MARCH, APRIL, MAY)

VALUES ('璧山', 33, 18, 17, 16, 206);

INSERT INTO TEST_LHR (NAME, JANUARY, FEBRUARY, MARCH, APRIL, MAY)

VALUES ('楊家坪', 72, 73, 79, 386, 327);

INSERT INTO TEST_LHR (NAME, JANUARY, FEBRUARY, MARCH, APRIL, MAY)

VALUES ('巫溪', 34, 9, 7, 21, 33);

INSERT INTO TEST_LHR (NAME, JANUARY, FEBRUARY, MARCH, APRIL, MAY)

VALUES ('豐都', 62, 46, 39, 36, 91);

INSERT INTO TEST_LHR (NAME, JANUARY, FEBRUARY, MARCH, APRIL, MAY)

VALUES ('武隆', 136, 86, 44, 52, 142);

COMMIT;

SELECT * FROM TEST_LHR;

 

下面進行列轉換:

SELECT *

  FROM (SELECT T.NAME, 'JANUARY' MONTH, T.JANUARY V_NUM

          FROM TEST_LHR T

        UNION ALL

        SELECT T.NAME, 'FEBRUARY' MONTH, T.FEBRUARY V_NUM

          FROM TEST_LHR T

        UNION ALL

        SELECT T.NAME, 'MARCH' MONTH, T.MARCH V_NUM

          FROM TEST_LHR T

        UNION ALL

        SELECT T.NAME, 'APRIL' MONTH, T.APRIL V_NUM

          FROM TEST_LHR T

        UNION ALL

        SELECT T.NAME, 'MAY' MONTH, T.MAY V_NUM

          FROM TEST_LHR T)

 ORDER BY NAME;

 

2、行轉列

行轉列就是將行數據內容做爲列名。示例代碼以下所示:

CREATE TABLE T_ROW_COL_LHR(

NUM VARCHAR2(15 CHAR),

NAME VARCHAR2(20 CHAR),

SEX VARCHAR2(2 CHAR),

CLASSES VARCHAR2(30 CHAR),

COURSE_NAME VARCHAR2(50 CHAR)

);

 

INSERT INTO T_ROW_COL_LHR(NUM,NAME,SEX,CLASSES,COURSE_NAME)  VALUES ('206211','王藝','','06-1','保險學');

INSERT INTO T_ROW_COL_LHR(NUM,NAME,SEX,CLASSES,COURSE_NAME) VALUES ('206212','肖薇','','06-2','保險學');

INSERT INTO T_ROW_COL_LHR(NUM,NAME,SEX,CLASSES,COURSE_NAME) VALUES ('206212','肖薇','','06-2','財務管理');

INSERT INTO T_ROW_COL_LHR(NUM,NAME,SEX,CLASSES,COURSE_NAME) VALUES ('206212','肖薇','','06-2','財務會計');

INSERT INTO T_ROW_COL_LHR(NUM,NAME,SEX,CLASSES,COURSE_NAME) VALUES ('206213','陳雅詩','','06-2','電子商務');

INSERT INTO T_ROW_COL_LHR(NUM,NAME,SEX,CLASSES,COURSE_NAME) VALUES ('206213','陳雅詩','','06-2','公共經濟學');

INSERT INTO T_ROW_COL_LHR(NUM,NAME,SEX,CLASSES,COURSE_NAME) VALUES ('206213','陳雅詩','','06-2','公司理財');

INSERT INTO T_ROW_COL_LHR(NUM,NAME,SEX,CLASSES,COURSE_NAME) VALUES ('206213','陳雅詩','','06-2','管理學原理');

INSERT INTO T_ROW_COL_LHR(NUM,NAME,SEX,CLASSES,COURSE_NAME) VALUES ('206213','陳雅詩','','06-2','保險學');

INSERT INTO T_ROW_COL_LHR(NUM,NAME,SEX,CLASSES,COURSE_NAME) VALUES ('206214','李丹陽','','06-1','保險學');

INSERT INTO T_ROW_COL_LHR(NUM,NAME,SEX,CLASSES,COURSE_NAME) VALUES ('206214','李丹陽','','06-1','財務管理');

INSERT INTO T_ROW_COL_LHR(NUM,NAME,SEX,CLASSES,COURSE_NAME) VALUES ('206214','李丹陽','','06-1','財務會計');

INSERT INTO T_ROW_COL_LHR(NUM,NAME,SEX,CLASSES,COURSE_NAME) VALUES ('206214','李丹陽','','06-1','電子商務');

INSERT INTO T_ROW_COL_LHR(NUM,NAME,SEX,CLASSES,COURSE_NAME) VALUES ('206214','李丹陽','','06-1','公共經濟學');

INSERT INTO T_ROW_COL_LHR(NUM,NAME,SEX,CLASSES,COURSE_NAME) VALUES ('206215','楊伊琳','','06-3','環境管理學');

INSERT INTO T_ROW_COL_LHR(NUM,NAME,SEX,CLASSES,COURSE_NAME) VALUES ('206215','楊伊琳','','06-3','管理學原理');

INSERT INTO T_ROW_COL_LHR(NUM,NAME,SEX,CLASSES,COURSE_NAME) VALUES ('206215','楊伊琳','','06-3','商務談判');

INSERT INTO T_ROW_COL_LHR(NUM,NAME,SEX,CLASSES,COURSE_NAME) VALUES ('206216','李佳琪','','06-2','土地估計');

SELECT * FROM T_ROW_COL_LHR;

 

COURSE_NAME進行行轉列:

SELECT NUM,NAME,SEX,CLASSES,

            MAX(DECODE(RN,1,COURSE_NAME,NULL)) COURSE_NAME_1,

            MAX(DECODE(RN,2,COURSE_NAME,NULL)) COURSE_NAME_2,

            MAX(DECODE(RN,3,COURSE_NAME,NULL)) COURSE_NAME_3,

            MAX(DECODE(RN,4,COURSE_NAME,NULL)) COURSE_NAME_4,

            MAX(DECODE(RN,5,COURSE_NAME,NULL)) COURSE_NAME_5

FROM   (SELECT NUM,NAME,SEX,CLASSES,COURSE_NAME,

ROW_NUMBER() OVER(PARTITION BY NUM,NAME,SEX,CLASSES ORDER BY COURSE_NAME) RN

                   FROM   T_ROW_COL_LHR)

GROUP  BY NUM,NAME,SEX,CLASSES;

結果以下所示:

 

COURSE_NAME列合併,示例代碼以下所示:

SELECT NUM,

       NAME,

       SEX,

       CLASSES,

       (MAX(DECODE(RN, 1, COURSE_NAME, NULL)) ||

       MAX(DECODE(RN, 2, ',' || COURSE_NAME, NULL)) ||

       MAX(DECODE(RN, 3, ',' || COURSE_NAME, NULL)) ||

       MAX(DECODE(RN, 4, ',' || COURSE_NAME, NULL)) ||

       MAX(DECODE(RN, 5, ',' || COURSE_NAME, NULL))) NAME

FROM   (SELECT NUM,

               NAME,

               SEX,

               CLASSES,

               COURSE_NAME,

               ROW_NUMBER() OVER(PARTITION BY NUM, NAME, SEX, CLASSES ORDER BY COURSE_NAME) RN

        FROM   T_ROW_COL_LHR)

GROUP  BY NUM,

          NAME,

          SEX,

          CLASSES;

結果以下所示:

 

3、多列轉換成字符串

使用||CONCAT函數實現。示例代碼以下所示。

SELECT CONCAT('A','B') FROM DUAL;

4、多行轉換成字符串

示例代碼以下所示

CREATE TABLE T_ROW_STR(

ID INT,

COL VARCHAR2(10)

);

INSERT INTO T_ROW_STR VALUES(1,'A');

INSERT INTO T_ROW_STR VALUES(1,'B');

INSERT INTO T_ROW_STR VALUES(1,'C');

INSERT INTO T_ROW_STR VALUES(2,'A');

INSERT INTO T_ROW_STR VALUES(2,'D');

INSERT INTO T_ROW_STR VALUES(2,'E');

INSERT INTO T_ROW_STR VALUES(3,'C');

COMMIT;

SELECT * FROM T_ROW_STR;

 

SELECT ID,

       MAX(DECODE(RN, 1, COL, NULL)) ||

       MAX(DECODE(RN, 2, ',' || COL, NULL)) ||

       MAX(DECODE(RN, 3, ',' || COL, NULL)) STR

FROM   (SELECT ID,

               COL,

               ROW_NUMBER() OVER(PARTITION BY ID ORDER BY COL) AS RN

        FROM   T_ROW_STR) T

GROUP  BY ID

ORDER  BY 1;

 

也能夠使用SYS_CONNECT_BY_PATH來實現:

SELECT T.ID ID,

       MAX(SUBSTR(SYS_CONNECT_BY_PATH(T.COL, ','), 2)) STR

FROM   (SELECT ID,

               COL,

               ROW_NUMBER() OVER(PARTITION BY ID ORDER BY COL) RN

        FROM   T_ROW_STR) T

START  WITH RN = 1

CONNECT BY RN = PRIOR RN + 1

    AND    ID = PRIOR ID

GROUP  BY T.ID;

 

5、字符串轉換成多列

實際上就是一個字符串拆分的問題。示例代碼以下所示:

CREATE TABLE T_COL_ROW(

ID INT,

C1 VARCHAR2(10),

C2 VARCHAR2(10),

C3 VARCHAR2(10));

 

INSERT INTO T_COL_ROW VALUES (1, 'v11', 'v21', 'v31');

INSERT INTO T_COL_ROW VALUES (2, 'v12', 'v22', NULL);

INSERT INTO T_COL_ROW VALUES (3, 'v13', NULL, 'v33');

INSERT INTO T_COL_ROW VALUES (4, NULL, 'v24', 'v34');

INSERT INTO T_COL_ROW VALUES (5, 'v15', NULL, NULL);

INSERT INTO T_COL_ROW VALUES (6, NULL, NULL, 'v35');

INSERT INTO T_COL_ROW VALUES (7, NULL, NULL, NULL);

COMMIT;

 

SELECT * FROM T_COL_ROW;

 

CREATE TABLE T_STR_COL AS

SELECT ID,C1||','||C2||','||C3 AS C123

FROM T_COL_ROW;

 

SELECT * FROM T_STR_COL;

 

SELECT ID,

       C123,

       SUBSTR(C123, 1, INSTR(C123 || ',', ',', 1, 1) - 1) C1,

       SUBSTR(C123,

              INSTR(C123 || ',', ',', 1, 1) + 1,

              INSTR(C123 || ',', ',', 1, 2) - INSTR(C123 || ',', ',', 1, 1) - 1) C2,

       SUBSTR(C123,

              INSTR(C123 || ',', ',', 1, 2) + 1,

              INSTR(C123 || ',', ',', 1, 3) - INSTR(C123 || ',', ',', 1, 2) - 1) C3

FROM   T_STR_COL

ORDER  BY 1;

 

6、字符串轉換成多行

示例代碼以下所示:

CREATE TABLE T_STR_ROW AS

SELECT ID,

       MAX(DECODE(RN, 1, COL, NULL)) ||

              MAX(DECODE(RN, 2, ',' || COL, NULL)) ||

              MAX(DECODE(RN, 3, ',' || COL, NULL)) STR

  FROM (SELECT ID,

               COL,

               ROW_NUMBER() OVER(PARTITION BY ID ORDER BY COL) AS RN

          FROM T_ROW_STR) T

  GROUP BY ID

  ORDER BY 1;

SELECT * FROM T_STR_ROW;

 

SELECT ID,

       1 AS P,

       SUBSTR(STR, 1, INSTR(STR || ',', ',', 1, 1) - 1) AS CV

FROM   T_STR_ROW

UNION ALL

SELECT ID,

       2 AS P,

       SUBSTR(STR,

              INSTR(STR || ',', ',', 1, 1) + 1,

              INSTR(STR || ',', ',', 1, 2) - INSTR(STR || ',', ',', 1, 1) - 1) AS CV

FROM   T_STR_ROW

UNION ALL

SELECT ID,

       3 AS P,

       SUBSTR(STR,

              INSTR(STR || ',', ',', 1, 1) + 1,

              INSTR(STR || ',', ',', 1, 2) - INSTR(STR || ',', ',', 1, 1) - 1) AS CV

FROM   T_STR_ROW

ORDER  BY 1,

          2;

 

還有幾類特殊的轉換,以下所示:

CREATE OR REPLACE TYPE INS_SEQ_TYPE IS VARRAY(8) OF NUMBER;

SELECT * FROM TABLE(INS_SEQ_TYPE(1, 2, 3, 4, 5));

結果:

COLUMN_VALUE

------------

           1

           2

           3

           4

           5

如果字符串類型,則以下所示:

CREATE OR REPLACE TYPE INS_SEQ_TYPE2 IS VARRAY(80) OF VARCHAR2(32767);

SELECT * FROM TABLE(INS_SEQ_TYPE2('aadf,dea','cbc','d'));

結果:

COLUMN_VALUE

-----------------

aadf,dea

cbc

d

還有以下的形式:

先建立一個TYPE類型,代碼以下:

CREATE OR REPLACE TYPE TYPE_STR_LHR IS TABLE OF VARCHAR2(32767);

再建立FUN_SPLIT2_LHR函數,代碼以下:

CREATE OR REPLACE FUNCTION FUN_SPLIT2_LHR(P_STR       VARCHAR2,

                                 V_SPLIT VARCHAR2 DEFAULT ',') RETURN TYPE_STR_LHR IS

  RS    TYPE_STR_LHR := TYPE_STR_LHR();

  V_STR VARCHAR2(4000) := '';

  V_LEN NUMBER := 0;

BEGIN

  V_STR := P_STR;

  V_LEN := LENGTH(V_SPLIT);

  WHILE LENGTH(V_STR) > 0 LOOP

    IF INSTR(V_STR, V_SPLIT) > 0 THEN

      RS.EXTEND;

      RS(RS.COUNT) := SUBSTR(V_STR, 1, INSTR(V_STR, V_SPLIT) - 1);

      V_STR := SUBSTR(V_STR, INSTR(V_STR, V_SPLIT) + V_LEN);

    ELSE

      RS.EXTEND;

      RS(RS.COUNT) := V_STR;

      EXIT;

    END IF;

  END LOOP;

  RETURN RS;

 

END;

測試以下:

SQL> SELECT COLUMN_VALUE FROM TABLE(FUN_SPLIT2_LHR('101,102,103',','));

 

COLUMN_VALUE

------------------

101

102

103

SQL> SELECT TO_NUMBER(COLUMN_VALUE) FROM TABLE(FUN_SPLIT2_LHR('101,102,103'));

 

TO_NUMBER(COLUMN_VALUE)

-----------------------

                   101

                   102

                   103

SQL> SELECT COLUMN_VALUE FROM TABLE(FUN_SPLIT2_LHR('101@#102@#103','@#'));

COLUMN_VALUE

---------------

101

102

103

& 說明:

有關行列互換更多的案例能夠參考個人BLOGhttp://blog.itpub.net/26736162/viewspace-1272538/



本文選自《Oracle程序員面試筆試寶典》,做者:李華榮。



watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=      

---------------優質麥課------------

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

 詳細內容能夠添加麥老師微信或QQ私聊。


watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=


About Me:小麥苗      

 本文做者:小麥苗,只專一於數據庫的技術,更注重技術的運用

● 做者博客地址:http://blog.itpub.net/26736162/abstract/1/

 本系列題目來源於做者的學習筆記,部分整理自網絡,如有侵權或不當之處還請諒解

 版權全部,歡迎分享本文,轉載請保留出處

 QQ:646634621  QQ羣:618766405

 提供OCP、OCM和高可用部分最實用的技能培訓

● 題目解答如有不當之處,還望各位朋友批評指正,共同進步

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

長按下圖識別二維碼或微信掃描下圖二維碼來關注小麥苗的微信公衆號:xiaomaimiaolhr,學習最實用的數據庫技術。

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=


本文分享自微信公衆號 - DB寶(lhrdba)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索