views:

4632

answers:

5

I'm trying to convert a single-columned subquery into a command-separated VARCHAR-typed list of values.

This is identical to this question, but for Oracle rather than SQL Server or MySQL.

+1  A: 

Here's a blog that shows an Oracle query to work like MySQL's GROUP_CONCAT():

http://halisway.blogspot.com/2006/08/oracle-groupconcat-updated-again.html

Bill Karwin
link to the original: http://tkyte.blogspot.com/2006/08/evolution.html
jimmyorr
+3  A: 

I found this that seems to work. Thoughts?

SELECT SUBSTR (c, 2) concatenated
  FROM (SELECT     SYS_CONNECT_BY_PATH ( myfield, ',') c, r
              FROM (SELECT   ROWNUM ID, myfield,
                             RANK () OVER (ORDER BY ROWID DESC) r
                        FROM mytable
                    ORDER BY myfield)
        START WITH ID = 1
        CONNECT BY PRIOR ID = ID - 1)
 WHERE r = 1;
Jason Cohen
Doesn't that break if your ID values are not continuous?
Bill Karwin
hmmm, yes I think you're right. :-(
Jason Cohen
I'm not sure why you have both a ROWNUM and a RANK() in your inner query. You probably only need the RANK() and then START WITH r = 1 CONNECT BY PRIOR r = r - 1. This doesn't require continuous ID's, since both the ID and the rank are getting generated.
Justin Cave
You do, however, probably want to use ROW_NUMBER() rather than RANK() in general. In this case it doesn't matter because ROWID is unique, but if you are ordering on a column that can potentially be non-unique, you don't want multiple rows with the same rank.
Justin Cave
+2  A: 

There is an excellent summary of the available string aggregation techniques on Tim Hall's site.

Justin Cave
A: 

11.2 introduced LISTAGG, which unlike WM_CONCAT is documented. We are not on 11.2 yet, so we use a custom aggregate function.

Leigh Riffel
A: 

SELECT deptno, wm_concat(ename) AS employees FROM emp GROUP BY deptno;

Reference: http://forums.oracle.com/forums/thread.jspa?messageID=1186901&#1186901

kalyan