`
easy0917
  • 浏览: 260355 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

行列转换

阅读更多
1、 固定列数的行列转换 如
  
 name subject grade
    ---------------------------
    student1 语文 80						      转换为                   
    student1 数学 70						       语文 数学 英语       
    student1 英语 60						       student1 80 70 60 
    student2 语文 90						       student2 90 80 100
    student2 数学 80
    student2 英语 100
  按照name分组得到的结果,所以decode外面要套个sum,不然group by出现语义错误,结果为
   
SELECT NAME,
           SUM(DECODE(SUBJECT, '语文', GRADE, NULL)) "语文",
           SUM(DECODE(SUBJECT, '数学', GRADE, NULL)) "数学",
           SUM(DECODE(SUBJECT, '英语', GRADE, NULL)) "英语"
      FROM STUDENT
     GROUP BY NAME
    2、 不定列行列转换
   如
    c1 c2
    --------------
    1 我
    1 是   转换为        
    1 谁 1 我是谁     
    2 知 2 知道        
    2 道 3 不           
    3 不
   
    这一类型的转换必须借助于PL/SQL 来完成,这里给一个例子
    
    CREATE OR REPLACE FUNCTION GET_C2(TMP_C1 NUMBER) RETURN VARCHAR2 IS
      COL_C2 VARCHAR2(4000);
    BEGIN
      FOR CUR IN (SELECT C2 FROM T WHERE C1 = TMP_C1) LOOP
        COL_C2 := COL_C2 || CUR.C2;
      END LOOP;
      COL_C2 := RTRIM(COL_C2, 1);
      RETURN COL_C2;
    END;
    /
 
  SQL> select distinct c1 ,get_c2(c1) cc2 from table;即可
    或者不用pl/sql,利用分析函数和 CONNECT_BY 实现:
    SELECT C1, SUBSTR(MAX(SYS_CONNECT_BY_PATH(C2, ';')), 2) NAME
      FROM (SELECT C1,
                   C2,
                   RN,
                   LEAD(RN) OVER(PARTITION BY C1 ORDER BY RN) RN1
              FROM (SELECT C1, C2, ROW_NUMBER() OVER(ORDER BY C2) RN FROM T))
     START WITH RN1 IS NULL
    CONNECT BY RN1 = PRIOR RN
     GROUP BY C1;
    3、列数不固定(交叉表行列转置)
    这种是比较麻烦的一种,需要借助pl/sql:
    原始数据:
 
  CLASS1 CALLDATE CALLCOUNT
    1 2005-08-08 40
    1 2005-08-07 6
    2 2005-08-08 77
    3 2005-08-09 33
    3 2005-08-08 9
    3 2005-08-07 21
   转置后:
    CALLDATE CallCount1 CallCount2 CallCount3
    ------------ ----------    ----------	----------
    2005-08-09	0		 0		 33
    2005-08-08	40		77		 9
    2005-08-07	6		0		21
   试验如下:
    1). 建立测试表和数据
引用
    CREATE TABLE t(
    class1 VARCHAR2(2 BYTE),
    calldate DATE,
    callcount INTEGER
    );
    INSERT INTO t(class1, calldate, callcount)
    VALUES ('1', TO_DATE ('08/08/2005', 'MM/DD/YYYY'), 40);
    INSERT INTO t(class1, calldate, callcount)
    VALUES ('1', TO_DATE ('08/07/2005', 'MM/DD/YYYY'), 6);
    INSERT INTO t(class1, calldate, callcount)
    VALUES ('2', TO_DATE ('08/08/2005', 'MM/DD/YYYY'), 77);
    INSERT INTO t(class1, calldate, callcount)
    VALUES ('3', TO_DATE ('08/09/2005', 'MM/DD/YYYY'), 33);
    INSERT INTO t(class1, calldate, callcount)
    VALUES ('3', TO_DATE ('08/08/2005', 'MM/DD/YYYY'), 9);
    INSERT INTO t(class1, calldate, callcount)
    VALUES ('3', TO_DATE ('08/07/2005', 'MM/DD/YYYY'), 21);
    COMMIT ;

    2) 建立ref cursor准备输出结果集
    CREATE OR REPLACE PACKAGE PKG_GETRECORD IS
      TYPE MYRCTYPE IS REF CURSOR;
    END PKG_GETRECORD;
    /
   3). 建立动态sql交叉表函数,输出结果集
    CREATE OR REPLACE FUNCTION FN_RS RETURN PKG_GETRECORD.MYRCTYPE IS
    S VARCHAR2(4000);
    CURSOR C1 IS
      SELECT ',sum(case when Class1=' || CLASS1 ||
             ' then CallCount else 0 end)' || ' "CallCount' || CLASS1 || '"' C2
        FROM T
       GROUP BY CLASS1;
    R1          C1%ROWTYPE;
    LIST_CURSOR PKG_GETRECORD.MYRCTYPE;
  BEGIN
    S := 'select CallDate ';
    OPEN C1;
    LOOP
      FETCH C1
        INTO R1;
      EXIT WHEN C1%NOTFOUND;
      S := S || R1.C2;
    END LOOP;
    CLOSE C1;
    S := S || ' from T group by CallDate order by CallDate desc ';
    OPEN LIST_CURSOR FOR S;
    RETURN LIST_CURSOR;
  END FN_RS;
  /
    4). 测试在sql plus下执行:
   var results refcursor;
    exec :results := fn_rs;
    print results;
    CALLDATE	CallCount1 CallCount2 CallCount3
    --------------- ----------	 ----------	  ----------
    2005-08-09		0		0		33
    2005-08-08		40		77		 9
    2005-08-07		6		0		21
   
   4、 不分组只简单行列互换,并且每组之间用虚线分割,可以使用procedure,代码如下:
    CREATE OR REPLACE PROCEDURE PRINT_TABLE(P_QUERY IN VARCHAR2) AUTHID CURRENT_USER AS
  L_THECURSOR   INTEGER DEFAULT DBMS_SQL.OPEN_CURSOR;
  L_COLUMNVALUE VARCHAR2(4000);
  L_STATUS      INTEGER;
  L_DESCTBL     DBMS_SQL.DESC_TAB;
  L_COLCNT      NUMBER;
BEGIN
  DBMS_SQL.PARSE(L_THECURSOR, P_QUERY, DBMS_SQL.NATIVE);
  DBMS_SQL.DESCRIBE_COLUMNS(L_THECURSOR, L_COLCNT, L_DESCTBL);
  FOR I IN 1 .. L_COLCNT LOOP
    DBMS_SQL.DEFINE_COLUMN(L_THECURSOR, I, L_COLUMNVALUE, 4000);
  END LOOP;
  L_STATUS := DBMS_SQL.EXECUTE(L_THECURSOR);
  WHILE (DBMS_SQL.FETCH_ROWS(L_THECURSOR) > 0) LOOP
    FOR I IN 1 .. L_COLCNT LOOP
      DBMS_SQL.COLUMN_VALUE(L_THECURSOR, I, L_COLUMNVALUE);
      DBMS_OUTPUT.PUT_LINE(RPAD(L_DESCTBL(I).COL_NAME, 30) || L_C
                           OLUMNVALUE);
    END LOOP;
    DBMS_OUTPUT.PUT_LINE('---------------------------------------------');
  END LOOP;
EXCEPTION
  WHEN OTHERS THEN
    DBMS_SQL.CLOSE_CURSOR(L_THECURSOR);
    RAISE;
    NULL;
END;
分享到:
评论

相关推荐

    sql行列转换扩展

    SQL 行列转换扩展 SQL 行列转换扩展是指将数据库表中的行数据转换为列数据,或者将列数据转换为行数据的操作。这种操作在数据分析和报表生成中非常常见。在本文中,我们将介绍两种类型的行列转换扩展方法:行转列...

    Excel行列转换工具

    在Excel表格处理中,行列转换是一项非常常见的操作,尤其对于数据整理和分析至关重要。"Excel行列转换工具"正是为了简化这一过程而设计的,它提供了一键式的转换功能,使得用户能够快速、高效地在行与列之间切换,极...

    oracle行列转换例子

    在Oracle数据库中,行列转换是一种常见的数据操作需求,主要用于将数据从行的形式转换为列的形式,或者反之。这种转换在数据分析、报表制作等场景中尤为常见。本文将深入解析一个Oracle行列转换的例子,通过详细解释...

    sql server 行列转换

    ### SQL Server 行列转换知识点解析 #### 一、行列转换概述 在处理数据库查询时,我们经常会遇到需要将表中的行数据转换为列数据的需求,这种操作通常被称为“行列转换”。例如,当我们需要汇总不同类别的数据并将...

    oracle行列转换总结

    在Oracle数据库中,行列转换是一项常用且强大的功能,它允许数据在不同的维度上进行转换,以便于数据分析和报告。本文将深入探讨Oracle中实现行列转换的几种方法,包括使用`UNION ALL`、`MODEL`子句以及集合类型(`...

    oracle行列转换实例

    【Oracle 行列转换实例】 在数据库管理中,有时我们需要将数据表的行与列进行转换,以便于数据分析和报表展示。Oracle 提供了一种高效的方法,即使用分析函数来实现这种行列转换。分析函数主要设计用于处理累计计算...

    SQL语句行列转换(附带数据库、表、视图操作)

    SQL 语句行列转换(附带数据库、表、视图操作) SQL 语句行列转换是数据库管理系统中的一种常见操作,它可以将数据从行转换为列,或者从列转换为行。在这个过程中,需要使用数据库管理语言(Database Management ...

    Oracle行列转换

    在处理数据时,有时我们需要将数据从行格式转换为列格式,或者反之,这一过程被称为“行列转换”。Oracle提供了多种方法来实现这样的转换,这对于数据分析、报表制作以及优化查询性能等场景非常有用。下面我们将深入...

    MSSQL行列转换存储过程

    其中,行列转换是数据处理中常见的一种需求,尤其是在进行数据分析、报表生成等场景时。本文将深入解析MSSQL中实现行列转换的存储过程及其工作原理,帮助读者理解和掌握这一关键技术。 ### MSSQL行列转换存储过程 ...

    行列互换工具毫秒级_V2.2.2行列转换.xlsm

    行列互换工具毫秒级_V2.2.2行列转换

    行列转换SQL存储过程代码

    ### 行列转换SQL存储过程代码解析 #### 核心知识点概述 本篇文章将深入探讨一个SQL存储过程的实现方式,该存储过程主要用于完成“行转列”(即行列转换)的操作。通过这种方式,可以有效地将数据库表中的行数据...

    oracle sql 行列转换

    在Oracle SQL中,行列转换是一种常见的数据操作需求,主要用于将数据表中的行转换为列,或将列转换为行,以此来满足不同的数据展示或分析需求。这种转换在处理多维度数据、汇总数据或是进行复杂查询时特别有用。下面...

    SQL 2008行列转换的pivot

    ### SQL 2008 行列转换 (Pivot) 的动态实现 #### 知识点一:行列转换(Pivot)的概念与应用场景 在数据库查询中,有时我们需要将数据表中的行转换为列,或者将列转换为行,这种操作被称为行列转换。行列转换在报表...

    一道java面试题 行列转换

    ### Java面试题:行列转换详解 #### 一、问题背景 在进行数据分析或者报表处理时,经常需要将数据从一种格式转换成另一种格式以便更好地展示或分析。其中一种常见的转换需求是从行转列(即行列转换)。本篇文章将...

    mysql 查询行列转换

    本篇文章将深入探讨“MySQL 查询行列转换”的概念及其实际应用,这在数据分析和报表展示时尤其重要。 行转列是数据处理中的常见需求,尤其是在数据透视或汇总分析时。在 MySQL 中,我们可以使用几种方法实现这一...

    sql查询中行列转换

    ### SQL查询中的行列转换 在数据库管理中,经常会遇到数据结构需要调整的情况,尤其是当原始数据的排列方式与实际需求不一致时。本篇文章将详细解释如何通过一条SQL查询语句实现行列转换,并且会针对两种不同的SQL ...

    Sql语句实现表的行列转换,行转列,列转行

    ### SQL语句实现表的行列转换,行转列,列转行 在处理数据库时,我们经常需要对数据进行各种变换以适应不同的分析需求。其中,“行列转换”就是一种非常实用的功能,它可以帮助我们将表中的行数据转换为列数据,...

    EXCEL 行列转换工具

    EXCEL 行列转换工具

Global site tag (gtag.js) - Google Analytics