我想要输出而不使用Oracle 10g中的case或decode

时间:2015-04-14 14:21:15

标签: sql oracle string-aggregation listagg

 STUD_ID SUBJECT              GRADE

 1       math                 a
 1       english              b
 1       computer             c
 2       math                 c
 2       lang                 a
 3       phys                 a
 3       chem                 b

输出应该是这样的:

  stud_id   grades
    1       a,b,c
    2       c,a
    3       a,b

1 个答案:

答案 0 :(得分:2)

如果您使用的是Oracle 11g及更高版本,则可以使用 LISTAGG 字符串聚合功能。

例如,

*SELECT deptno, LISTAGG(ename, ',') WITHIN GROUP (ORDER BY ename) AS employees
FROM   emp
GROUP BY deptno;

    DEPTNO EMPLOYEES
---------- --------------------------------------------------
        10 CLARK,KING,MILLER
        20 ADAMS,FORD,JONES,SCOTT,SMITH
        30 ALLEN,BLAKE,JAMES,MARTIN,TURNER,WARD

3 rows selected.

对于其他特定于版本的解决方案,请参阅演示的示例here

注意请记住,请勿使用wm_concat,它在之前的12c版本中没有记录,12c不支持。有关详细信息,请参阅我的回答here

更新关于OP关于10g解决方案的请求。

Tim Hall的文章中提到了两种方式:

    Oracle 10g
  • 收集功能

例如,

CREATE OR REPLACE TYPE t_varchar2_tab AS TABLE OF VARCHAR2(4000);
/

CREATE OR REPLACE FUNCTION tab_to_string (p_varchar2_tab  IN  t_varchar2_tab,
                                          p_delimiter     IN  VARCHAR2 DEFAULT ',') RETURN VARCHAR2 IS
  l_string     VARCHAR2(32767);
BEGIN
  FOR i IN p_varchar2_tab.FIRST .. p_varchar2_tab.LAST LOOP
    IF i != p_varchar2_tab.FIRST THEN
      l_string := l_string || p_delimiter;
    END IF;
    l_string := l_string || p_varchar2_tab(i);
  END LOOP;
  RETURN l_string;
END tab_to_string;
/
    ROW_NUMBER() SYS_CONNECT_BY_PATH Oracle 9i 及更高版本中运行

例如,

SELECT deptno,
       LTRIM(MAX(SYS_CONNECT_BY_PATH(ename,','))
       KEEP (DENSE_RANK LAST ORDER BY curr),',') AS employees
FROM   (SELECT deptno,
               ename,
               ROW_NUMBER() OVER (PARTITION BY deptno ORDER BY ename) AS curr,
               ROW_NUMBER() OVER (PARTITION BY deptno ORDER BY ename) -1 AS prev
        FROM   emp)
GROUP BY deptno
CONNECT BY prev = PRIOR curr AND deptno = PRIOR deptno
START WITH curr = 1;

    DEPTNO EMPLOYEES
---------- --------------------------------------------------
        10 CLARK,KING,MILLER
        20 ADAMS,FORD,JONES,SCOTT,SMITH
        30 ALLEN,BLAKE,JAMES,MARTIN,TURNER,WARD

3 rows selected.