I have a table that has data like this
Group Value
1 A
1 B
1 C
2 F
2 G
3 J
3 K
I want to join all members of one group to all members of each of the other groups into a single column like this:
AFJ
AFK
AGJ
AGK
BFJ
BFK
BGJ
BGK
CFJ
CFK
CGJ
CGK
There can be n number of groups and n number of values
Thank you
SQL does not offer many options for such a query. The one standard method is a recursive CTE. Other methods would involve recursive functions or stored procedures.
The following is an example of a recursive CTE that solves this problem:
with groups as (
select v.*
from (values (1, 'a'), (1, 'b'), (1, 'c'), (2, 'f'), (2, 'g'), (3, 'h'), (3, 'k')
) v(g, val)
),
cte as (
select 1 as groupid, val, 1 as lev
from groups
where g = 1
union all
select cte.groupid + 1, cte.val + g.val, lev + 1
from cte join
groups g
on g.g = cte.groupid + 1
)
select val
from (select cte.*, max(lev) over () as max_lev
from cte
) cte
where lev = max_lev
order by 1;
Some databases that support recursive CTEs don't use the recursive
keyword.
Here is a db<>fiddle .
If you need to consider gaps between the groups, ie Group 1, then no 2, then 3.
with t(Grp, val) as (
select 1, 'A' from dual
union all
select 1, 'B' from dual
union all
select 1, 'C' from dual
union all
select 2, 'F' from dual
union all
select 2, 'G' from dual
union all
select 3, 'J' from dual
union all
select 3, 'K' from dual
)
, grpIndexes as (
SELECT ROWNUM indx
, grp
FROM (select distinct
grp
from t)
)
, Grps as (
select t.*
, grpIndexes.indx
from t
inner join grpIndexes
on grpIndexes.grp = t.grp
)
, rt(val, indx, lvl) as (
select val
, indx
, 0 as lvl
from Grps
where indx = (select min(indx) from Grps)
union all
select previous.val || this.val as val
, this.indx
, previous.lvl + 1 as lvl
from rt previous
, Grps this
where this.indx = (select min(indx) from Grps where indx > previous.indx)
and previous.indx <> (select max(indx) from Grps)
)
select val
from rt
where lvl = (select max(lvl) from rt)
order by val
;
Note that I renamed the columns because Group and Value are reserved words.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.