Sfortunatamente non c'è PIVOT in Teradata (solo un TD_UNPIVOT in 14.10).
Se hai fortuna c'è un UDF aggregato nel tuo sito per fare un concat di gruppo (probabilmente bassa possibilità).
Altrimenti ci sono due opzioni: ricorsione o aggregazione.
Se il numero massimo di righe per ID è noto, l'aggregazione è normalmente più veloce. È un sacco di codice, ma la maggior parte si basa sul taglio & incolla.
SELECT
id,
MAX(CASE WHEN rn = 1 THEN string END)
|| MAX(CASE WHEN rn = 2 THEN ',' || string ELSE '' END)
|| MAX(CASE WHEN rn = 3 THEN ',' || string ELSE '' END)
|| MAX(CASE WHEN rn = 4 THEN ',' || string ELSE '' END)
|| ... -- repeat up to the known maximum
FROM
(
SELECT
id, string,
ROW_NUMBER()
OVER (PARTITION BY id
ORDER BY string) AS rn
FROM t
) AS dt
GROUP BY 1;
Per tabelle di grandi dimensioni è molto più efficiente quando si materializzare il risultato della tabella derivata in una tabella volatile prima utilizzando GROUP BY colonna come PI.
Per la ricorsione è necessario utilizzare anche una tabella volatile, poiché le funzioni OLAP non sono consentite nella parte ricorsiva. L'utilizzo di una vista, invece, calcola ripetutamente la funzione OLAP e quindi porta a prestazioni non buone.
CREATE VOLATILE TABLE vt AS
(
SELECT
id
,string
,ROW_NUMBER()
OVER (PARTITION BY id
ORDER BY string DESC) AS rn -- reverse order!
,COUNT(*)
OVER (PARTITION BY id) AS cnt
FROM t
) WITH DATA
UNIQUE PRIMARY INDEX(id, rn)
ON COMMIT PRESERVE ROWS;
WITH RECURSIVE cte
(id, list, rn) AS
(
SELECT
id
,CAST(string AS VARCHAR(1000)) -- define maximum size based on maximum number of rows
,rn
FROM vt
WHERE rn = cnt
UNION ALL
SELECT
vt.id
,cte.list || ',' || vt.string
,vt.rn
FROM vt
JOIN cte
ON vt.id = cte.id
AND vt.rn = cte.rn - 1
)
SELECT id, list
FROM cte
WHERE rn = 1;
C'è un problema con questo approccio, si potrebbe aver bisogno di un sacco di rocchetto che è facile da vedere quando si omette il WHERE rn = 1
.
Grazie per il reindirizzamento –
Questo mi ha aiutato moltissimo, grazie. –