1

I have table structure like below

create table emp ( empno number,dept_no varchar(4));
insert into emp VALUES  (1,'A');
insert into emp  VALUES (1,'B');
insert into emp  VALUES (1,'C');
insert into emp  VALUES (1,'D');
insert into emp  VALUES (2,'P');
insert into emp  VALUES (2,'Q');
insert into emp  VALUES (2,'R');
insert into emp  VALUES (2,'S');

I need output like below

1, A
1, A,B
1, A,B,C
1, A,B,C,D
2, P
2, P,Q
2, P,Q,R
2, P,Q,R,S

I am able to achieve this using PL/SQL Block, however is there any possibility we can achieve this through sql?

2
  • 1
    Where did those 10s and 20s come from? Commented Feb 16, 2020 at 21:00
  • Correct the output now Commented Feb 16, 2020 at 21:03

2 Answers 2

4

This is a task for listagg(). Unfortunately, although it can be used as window function, it does not support the order by window option, which is needed here.

One way to work around this would be to use a correlated subquery:

select 
    e.empno,
    (
            select listagg(e1.dept_no, ',') within group(order by e1.dept_no)
            from emp e1
            where e1.empno = e.empno and e1.dept_no <= e.dept_no            
    ) depts
from emp e

Demo on DB Fiddlde:

EMPNO | DEPTS  
----: | :------
    1 | A      
    1 | A,B    
    1 | A,B,C  
    1 | A,B,C,D
    2 | P      
    2 | P,Q    
    2 | P,Q,R  
    2 | P,Q,R,S
Sign up to request clarification or add additional context in comments.

5 Comments

Can you please explain that final / after the end; in the fiddle? Without it, web site brings me error. Kindly thank you.
@ЯрославМашко: that's a trick to run the inserts in a batch. Otherwise, db<>fiddle wants each insert statement as a separate entry, which is tedious to write. Note: nice to see that you actually checked the fiddle!
I am thinking about... Is it possible to have this question answered with a recursive cte solution? But I have a serious issue for now. The recursive cte's only work in postgres for me. Nor did the "uk" web site, nor is the other web sites allow me to have a recursive syntax with the Oracle. Maybe, by coincedence, you know why it is so? At the end of my trial, I had copy/pasted the official Oracle docs(recursive example) from here: docs.oracle.com/cd/E17952_01/mysql-8.0-en/…. And there were errors still.
@ЯрославМашко: you are reading the MySQL documentation on Oracle website. Oracle does support hierarchical queries, and this is a viable option here; however I would expect that this would be less efficient than the correlated subquery solution.
My mistake. Oracle seems to omit the recursive keyword.
0

Apart from good answer from @gmb, you can also try following option where table will be traverse only once.

SELECT empno,
    LTRIM(SYS_CONNECT_BY_PATH(dept_no,','),',') AS employees
FROM   (SELECT dept_no,
               empno,
               ROW_NUMBER() OVER (PARTITION BY empno ORDER BY dept_no) AS curr,
               ROW_NUMBER() OVER (PARTITION BY empno ORDER BY dept_no) -1 AS prev
        FROM   emp)
CONNECT BY prev = PRIOR curr
  AND empno = PRIOR empno
START WITH curr = 1;

Db<>fiddle demo

Cheers!!

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.