Campi concatenati che utilizzano Connect by Prior
-
28-10-2019 - |
Domanda
Avere la tabella seguente my_tabe
:
M01 | 1
M01 | 2
M02 | 1
Voglio interrogarlo per ottenere:
M01 | 1,2
M02 | 1
Sono riuscito a avvicinarmi usando la seguente query:
with my_tabe as
(
select 'M01' as scycle, '1' as sdate from dual union
select 'M01' as scycle, '2' as sdate from dual union
select 'M02' as scycle, '1' as sdate from dual
)
SELECT scycle, ltrim(sys_connect_by_path(sdate, ','), ',')
FROM
(
select scycle, sdate, rownum rn
from my_tabe
order by 1 desc
)
START WITH rn = 1
CONNECT BY PRIOR rn = rn - 1
Cedendo:
SCYCLE | RES
M02 | 1,2,1
M01 | 1,2
Che è sbagliato. Sembra che io sia vicino, ma temo di non farlo qual è il prossimo passo ...
Qualche consiglio?
Soluzione
Devi limitare il tuo connect by
allo stesso scycle
valore, e conta anche il numero di corrispondenze e filtra su questo per evitare di vedere risultati intermedi.
with my_tabe as
(
select 'M01' as scycle, '1' as sdate from dual union
select 'M01' as scycle, '2' as sdate from dual union
select 'M02' as scycle, '1' as sdate from dual
)
select scycle, ltrim(sys_connect_by_path(sdate, ','), ',')
from
(
select distinct sdate,
scycle,
count(1) over (partition by scycle) as cnt,
row_number() over (partition by scycle order by sdate) as rn
from my_tabe
)
where rn = cnt
start with rn = 1
connect by prior rn + 1 = rn
and prior scycle = scycle
/
SCYCLE LTRIM(SYS_CONNECT_BY_PATH(SDATE,','),',')
------ -----------------------------------------
M01 1,2
M02 1
Se sei su 11g puoi usare il integrato LISTAGG
funzione invece:
with my_tabe as
(
select 'M01' as scycle, '1' as sdate from dual union
select 'M01' as scycle, '2' as sdate from dual union
select 'M02' as scycle, '1' as sdate from dual
)
select scycle, listagg (sdate, ',')
within group (order by sdate) res
from my_tabe
group by scycle
/
Vengono mostrati entrambi gli approcci (e gli altri) qui.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow