Create test table
create table listagg_test(a number generated by default on null as identity
,grp number
,name varchar2(50))
Table created.
insert into listagg_test (grp, name) values (1,'Lemar')
1 row(s) inserted.
insert into listagg_test (grp, name) values (1,'Einstein')
1 row(s) inserted.
insert into listagg_test (grp, name) values (1,'Turing')
1 row(s) inserted.
insert into listagg_test (grp, name) values (2,'Kepler')
1 row(s) inserted.
insert into listagg_test (grp, name) values (2,'Lovelace')
1 row(s) inserted.
insert into listagg_test (grp, name) values (4,'Eugenie')
1 row(s) inserted.
insert into listagg_test (grp, name) values (4,'Novella')
1 row(s) inserted.
insert into listagg_test (grp, name) values (4,'Novella')
1 row(s) inserted.
insert into listagg_test (grp, name) values (4,'Tyson')
1 row(s) inserted.
insert into listagg_test (grp, name) values (3,'Zappa')
1 row(s) inserted.
insert into listagg_test (grp, name) values (5,'')
1 row(s) inserted.
Group by SQL
select grp
,count(*) cnt
,listagg(name,', ') within group (order by name) names
,Min(name) KEEP (DENSE_RANK first ORDER BY name) first_name
from listagg_test
group by grp
GRP | CNT | NAMES | FIRST_NAME | 1 | 3 | Einstein, Lemar, Turing | Einstein | 2 | 2 | Kepler, Lovelace | Kepler | 3 | 1 | Zappa | Zappa | 4 | 4 | Eugenie, Novella, Novella, Tyson | Eugenie | 5 | 1 | - | - |
---|
Row level analytics
select t.*
-- inline view required to split secondary names?
,listagg(case when rank_person_group != 1 then name end,', ')
within group (order by rank_person_group)
over (partition by t.grp) secondary_names
from (
select a, grp, name -- standard columns
-- unique names overall
,count(distinct name)
over () cnt
-- names by group
,count(name)
over (partition by grp) cnt_group
-- rank names within group
,dense_rank() over (partition by grp order by name asc) rank_person_group
-- allocate unique number to each name
,row_number() over (order by name asc) number_person
-- aggregate names
,listagg(name,', ') within group (order by name)
over (partition by grp) names
-- show first name only
,min(name) keep (dense_rank first order by name)
over (partition by grp) first_name
-- alternative method, tweaked for last name
,first_value(name)
over (partition by grp order by name desc) final_name
from listagg_test
) t
A | GRP | NAME | CNT | CNT_GROUP | RANK_PERSON_GROUP | NUMBER_PERSON | NAMES | FIRST_NAME | FINAL_NAME | SECONDARY_NAMES | 2 | 1 | Einstein | 9 | 3 | 1 | 1 | Einstein, Lemar, Turing | Einstein | Turing | Lemar, Turing | 1 | 1 | Lemar | 9 | 3 | 2 | 4 | Einstein, Lemar, Turing | Einstein | Turing | Lemar, Turing | 3 | 1 | Turing | 9 | 3 | 3 | 8 | Einstein, Lemar, Turing | Einstein | Turing | Lemar, Turing | 4 | 2 | Kepler | 9 | 2 | 1 | 3 | Kepler, Lovelace | Kepler | Lovelace | Lovelace | 5 | 2 | Lovelace | 9 | 2 | 2 | 5 | Kepler, Lovelace | Kepler | Lovelace | Lovelace | 10 | 3 | Zappa | 9 | 1 | 1 | 10 | Zappa | Zappa | Zappa | - | 6 | 4 | Eugenie | 9 | 4 | 1 | 2 | Eugenie, Novella, Novella, Tyson | Eugenie | Tyson | Novella, Novella, Tyson | 7 | 4 | Novella | 9 | 4 | 2 | 6 | Eugenie, Novella, Novella, Tyson | Eugenie | Tyson | Novella, Novella, Tyson | 8 | 4 | Novella | 9 | 4 | 2 | 7 | Eugenie, Novella, Novella, Tyson | Eugenie | Tyson | Novella, Novella, Tyson | 9 | 4 | Tyson | 9 | 4 | 3 | 9 | Eugenie, Novella, Novella, Tyson | Eugenie | Tyson | Novella, Novella, Tyson | 11 | 5 | - | 9 | 0 | 1 | 11 | - | - | - | - |
---|