I am working with data that is represented using the following basic syntax:
a→b→c
EDIT
This is used to describe a spatiotemporal relation of alteration assemblages around an ore deposit. An alteration assemblage can either be spatially or temporally related to the mineralisation of a deposit, which could be constructed as such
(a[proximal]→b→c[distal])[early]→(d[proximal]→e→f[distal])[late]
Both the groups a, b, c and d, e, f are spatial relations to the ore deposit, and these two groups can be temporally related to each other. These can get more complex, in full they often look like this:
(ksp-cal-cpx±anr [early] → cpx-act-scp-cal-mt±adr±tm±all±ap±bt±ksp → chl-ep-cal-cp-py-mt [late]) [proximal] → cpx±amp±scp → qtz-hm-ab-ser-cal±scp±py±po±fl [distal]
(Note: the 'proximal', 'distal', 'early', and 'late' descriptors in square brackets are often, but not always, present. The syntax like 'ksp-cal-cpx±anr' is a mineral assemblage, which I have abstracted away with a, b, c, etc in my examples)
In my table I represent a→b→c in the following way
| ID | TERM | PARENT | GROUP_LEVEL |
|---|---|---|---|
| 1 | a | 1 | |
| 2 | b | 1 | 1 |
| 3 | c | 2 | 1 |
Sometimes these data can have nested groups, eg
a→(b→c)
I indicate the change of level of these groups using the fourth column GROUP_LEVEL
| ID | TERM | PARENT | GROUP_LEVEL |
|---|---|---|---|
| 4 | a | 1 | |
| 5 | b | 4 | 2 |
| 6 | c | 5 | 2 |
The nesting can potentially get more complex, eg
a→((b→c)→d→(e→f))
The table is then structured as follows:
| ID | TERM | PARENT | GROUP_LEVEL |
|---|---|---|---|
| 7 | a | 1 | |
| 8 | b | 7 | 3 |
| 9 | c | 8 | 3 |
| 10 | d | 8 | 2 |
| 11 | e | 10 | 3 |
| 12 | f | 11 | 3 |
I've tried using the following SQL, but cannot get it to work
with hierarchical_terms as
(select
CONNECT_BY_ROOT id as id,
level as term_level,
term,
group_level,
connect_by_isleaf leaf_node,
row_number()
over (PARTITION BY CONNECT_BY_ROOT id, group_level ORDER BY term nulls last) as group_order
from test_groupings tg
connect by prior tg.id = tg.parent start with parent is null
)
select id,
listagg (
case when term_level =1 then
term
when term_level > 1 then
case when group_level > 1 and group_order = 1 then
'→('||term
when group_level > 1 and leaf_node = 1 then
'→'|| term || ')'
else
'→'||term
end
end,
'') as terms
from hierarchical_terms
group by id
However this doesn't quite work, row in bold is not formatted the way I like it.
| ID | TERMS |
|---|---|
| 1 | a→b→c |
| 4 | a→(b→c) |
| 7 | a→(d→(b→c)→e→f) |
What I want is for each 'group level' to be encapsulate by parentheses, and then connected by their hierarchical relations. But I can't seem to achieve this no matter what I try.
Any help would be greatly appreciated.
You may not be able to do this in SQL, but you can do it in PL/SQL:
Create the types:
With the bodies:
Then you can create a pipelined function:
Then the output from the function:
For the sample data:
Is:
db<>fiddle here