Skip to Main Content

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, renji.

Asked: May 08, 2013 - 11:29 pm UTC

Last updated: May 09, 2013 - 7:08 pm UTC

Version: oracle 11g

Viewed 10K+ times! This question is

You Asked

I have an employee table and the structure of the table is



create table
employee(empid number,empname varchar2(15)
,child1_name varchar2(15),child2_name varchar2(15),child3_name varchar2(15),child4_name varchar2(15))




I want to display the empid,emp name and all childrens name concatenated with comma as the seperator. The names of the kids should be sorted

so a sample row
is
insert into employee
values(1, 'joe','shane','paul','rob',null);

and the expected result should be

1, joe, paul,rob,shane


Could you help how to achieve it using sql (by not using pl/sql)


Thanks,
Joseph

and Tom said...

think about how *trivial* this would have been had you modeled the data correctly - using a child table (all pun intended!)

Now we have to blow the data out and then aggregate it...


ops$tkyte%ORA11GR2> select empid, empname, listagg(cname,',') within group (order by cname) cnames
  2    from (
  3  select empid, empname, decode( r, 1, child1_name, 2, child2_name, 3, child3_name, 4, child4_name ) cname
  4    from employee, (select level r from dual connect by level <= 4)
  5   where decode( r, 1, child1_name, 2, child2_name, 3, child3_name, 4, child4_name ) is not null
  6         )
  7   group by empid, empname
  8   order by empid
  9  /

     EMPID EMPNAME         CNAMES
---------- --------------- ------------------------------
         1 joe             paul,rob,shane


Rating

  (5 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

CHILDREN >4

Steve, May 09, 2013 - 3:47 pm UTC

renji,

What do you do if someone has more than 4 children?
Tom Kyte
May 09, 2013 - 5:05 pm UTC

:) indeed!

To Steve

Rajeshwaran, Jeyabal, May 09, 2013 - 5:51 pm UTC

What do you do if someone has more than 4 children -Just unpivot it and sort them back.

drop table t purge;
create table t(x int,c1 varchar2(2),
c2 varchar2(2), c3 varchar2(2),c4  varchar2(2),
c5 varchar2(3), c6  varchar2(7));

insert into t values(1,'a','c','b','e',null,'d');
insert into t values(2,'aa','c','be','ee',null,'ad');
commit;

rajesh@ORA11G> select x,
  2    listagg(val,',') within group(order by val) y
  3  from ( select c1,c2,c3,c4,c5,c6,x from t )
  4  unpivot exclude nulls
  5  ( val for key in (c1,c2,c3,c4,c5,c6) )
  6  group by x ;

         X Y
---------- --------------------
         1 a,b,c,d,e
         2 aa,ad,be,c,ee

2 rows selected.

why not concatenate?

S T, May 09, 2013 - 6:46 pm UTC

Why can't we just do
select empid,child_name1||','||child_name2..from table??

I am sure i'm missing something otherwise, it seems pretty obvious..
Tom Kyte
May 09, 2013 - 7:08 pm UTC

The names of the kids should be sorted

sorry! I got it

S T, May 09, 2013 - 6:48 pm UTC

Please disregard my earlier comment.. It's all about sorting isn't it :-)

TO Rajeshwaran, Jeyabal

Steve, May 09, 2013 - 7:03 pm UTC

The original poster can't do that. His table can only take 4 children as programmed. He would need to add more columns to hold the data. That was what i was hinting at...