美文网首页
oracle行列转换

oracle行列转换

作者: 爱恨_交加 | 来源:发表于2020-11-05 14:16 被阅读0次

    行转列

    建表、插数

    create table transcript
    (
      id     NUMBER,
      name   VARCHAR2(20),
      course VARCHAR2(20),
      score  NUMBER
    );
    insert into transcript (id, name, course, score) values (1, '张三', '语文', 67);
    insert into transcript (id, name, course, score) values (1, '张三', '数学', 76);
    insert into transcript (id, name, course, score) values (1, '张三', '英语', 43);
    insert into transcript (id, name, course, score) values (2, '李四', '语文', 54);
    insert into transcript (id, name, course, score) values (2, '李四', '数学', 81);
    insert into transcript (id, name, course, score) values (2, '李四', '英语', 64);
    insert into transcript (id, name, course, score) values (3, '王五', '语文', 24);
    insert into transcript (id, name, course, score) values (3, '王五', '数学', 25);
    insert into transcript (id, name, course, score) values (3, '王五', '英语', 8);
    commit;
    

    转换方式

    CASE

    -- 可以使用 MAX替代 SUM,但 MIN 不可以
    SELECT ID,NAME,
    SUM(CASE WHEN course='语文' THEN score ELSE 0 END) 语文,
    SUM(CASE WHEN course='数学' THEN score ELSE 0 END) 数学,
    SUM(CASE WHEN course='英语' THEN score ELSE 0 END) 英语
    FROM transcript
    GROUP BY ID ,NAME
    

    DECODE

    -- 可以使用 SUM 替代 MAX,但 MIN 不可以
    SELECT ID,NAME,
    MAX(DECODE(course,'语文',score,0)) 语文,
    MAX(DECODE(course,'数学',score,0)) 数学,
    MAX(DECODE(course,'英语',score,0)) 英语
    FROM transcript
    GROUP BY ID ,NAME
    

    PIVOT

    SELECT * FROM transcript
    PIVOT(SUM(score) FOR course IN('语文' as 语文,'数学' as 数学,'英语' as 英语));
    

    wmsys.wm_concat

    SELECT ID,NAME,
    wmsys.wm_concat(course || ':'||score) course
    FROM transcript
    GROUP BY ID,NAME;
    

    PL/SQL

    DECLARE
      --判断表是否存在
      TAB_EXISTS INTEGER;
      --存放最终的SQL
      LV_SQL VARCHAR2(3000);
      --存放连接的SQL
      SQL_COMMOND VARCHAR2(3000);
      --定义课程游标
      CURSOR CUR IS
        SELECT COURSE FROM transcript GROUP BY COURSE;
    BEGIN
      --定义查询开头
      SQL_COMMOND := 'SELECT ID,NAME ';
    
      FOR I IN CUR LOOP
        --将结果相连接
        SQL_COMMOND := SQL_COMMOND || ' ,SUM(DECODE(COURSE,''' || I.COURSE || ''',SCORE,0)) ' || I.COURSE;
        DBMS_OUTPUT.PUT_LINE(SQL_COMMOND);
      END LOOP;
      SQL_COMMOND := SQL_COMMOND || ' FROM TRANSSCRIPT GROUP BY NAME';
      
      -- 判断表是否存在,存在则删除
      SELECT COUNT(*) INTO TAB_EXISTS FROM USER_TABLES WHERE table_name = 'TRANSSCRIPT_TMP'; 
      IF TAB_EXISTS > 0 THEN
        DBMS_OUTPUT.PUT_LINE('该表已经存在!');
        EXECUTE IMMEDIATE 'DROP TABLE TRANSSCRIPT_TMP';
      ELSE
        DBMS_OUTPUT.PUT_LINE('该表并不存在!');
      END IF;    
    
      --生成并执行最终SQL
      LV_SQL := 'CREATE TABLE TRANSSCRIPT_TMP ' || SQL_COMMOND;
      DBMS_OUTPUT.PUT_LINE(LV_SQL);
      EXECUTE IMMEDIATE LV_SQL;
    END;
    
    --查询结果
    SELECT * FROM TRANSCRIPT_TMP;
    

    列转行

    建表、插数

    create table transcript
    (
      id   NUMBER,
      name VARCHAR2(20),
      语文 NUMBER,
      数学 NUMBER,
      英语 NUMBER
    );
    insert into transcript (id,name,语文,数学,英语) values(1,'张三',71,72,73);
    insert into transcript (id,name,语文,数学,英语) values(2,'李四',81,82,83);
    insert into transcript (id,name,语文,数学,英语) values(3,'王五',91,92,93);
    commit;
    

    转换方式

    UNPIVOT

    select id,name, course, score
    from transcript 
    unpivot((score) for course in(语文,数学,英语));
    

    相关文章

      网友评论

          本文标题:oracle行列转换

          本文链接:https://www.haomeiwen.com/subject/mugovktx.html