如何在不使用PIVOT的情况下将sql选择查询结果作为列vs值而不是行方式

时间:2016-04-07 08:28:40

标签: oracle

假设我有一张叫做学生的桌子:

当我从该表中选择时,结果为:

SQL> select * from student;
NAME                 ROLL_NO
-------------------- --------------------
gokul                3
gokul1               34

我们可以得到这样的输出吗?不使用PIVOT关键字

SQL> select * from student;

NAME     gokul       gokul1     
ROLL_NO  3           34

1 个答案:

答案 0 :(得分:0)

简单的答案是:不,你不能。

在Oracle中,可以执行dynamic pivot on an unknown number of columns,但使用简单的SELECT * FROM student不能做到这一点。您将需要使用PL / SQL来构建一些动态SQL:

VARIABLE cur REFCURSOR;

DECLARE
  p_sql CLOB;
BEGIN
  SELECT 'SELECT ''ROLL_NO'' AS "NAME", '
         || LISTAGG(
              'MAX( CASE name WHEN '''
                || name
                || ''' THEN roll_no END ) AS "'
                || name || '"',
              ','
            ) WITHIN GROUP ( ORDER BY ROWNUM )
         || ' FROM students'
  INTO   p_sql
  FROM   students;

  OPEN :cur FOR p_sql;
END;
/

PRINT cur;

<强>输出

NAME    gokul       gokul1     
------- ----------- -----------
ROLL_NO 3           34

修改

上面的代码适用于LISTAGG输出低于4000字节的情况,但是如果你想要查看它,那么你需要一个稍微不同的方法:

VARIABLE cur REFCURSOR;

DECLARE
  TYPE name_t IS TABLE OF students.name%type;
  p_sql CLOB;
  names name_t;
BEGIN
  SELECT DISTINCT name
  BULK COLLECT INTO names
  FROM   students;

  p_sql := EMPTY_CLOB() || 'SELECT ''ROLL_NO'' AS "NAME"';
  FOR i IN 1 .. names.COUNT LOOP
    p_sql := p_sql || ', MAX( CASE name WHEN '''
                   || names(i)
                   || ''' THEN roll_no END ) AS "'
                   || names(i)
                   || '"';
  END LOOP;
  p_sql := p_sql || ' FROM students';

  OPEN :cur FOR p_sql;
END;
/

PRINT cur;