不幸的是,Teradata 中没有 PIVOT(14.10 中只有 TD_UNPIVOT)。
如果你运气好的话,你的站点上有一个聚合的 UDF 可以进行组连接(可能可能性很小)。
否则有两种选择:递归或聚合。
如果每个 id 的最大行数已知,聚合通常会更快。代码很多,但大部分都是基于剪切和粘贴的。
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;
对于大型表,当您首先使用 GROUP BY 列作为 PI 在易失性表中具体化派生表的结果时,效率会更高。
对于递归,您也应该使用易失性表,因为递归部分中不允许使用 OLAP 函数。改用视图会重复计算 OLAP 函数,从而导致性能下降。
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;
这种方法有一个问题,它可能需要大量的线轴,当你省略WHERE rn = 1
.