use*_*246 8 concat teradata partition
我正在使用Teradata,我有一张这样的桌子
ID String
123 Jim
123 John
123 Jane
321 Jill
321 Janine
321 Johan
Run Code Online (Sandbox Code Playgroud)
我想查询表,所以我得到了
ID String
123 Jim, John, Jane
321 Jill, Janine, Johan
Run Code Online (Sandbox Code Playgroud)
我试过分区,但可以有很多名字.我如何得到这个结果.甚至,指出我正确的方向将是伟大的.
不幸的是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;
Run Code Online (Sandbox Code Playgroud)
对于大型表,当您首先使用GROUP BY列作为PI实现Volatile Table中的派生表的结果时,它会更有效.
对于递归,您也应该使用易失性表,因为递归部分中不允许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;
Run Code Online (Sandbox Code Playgroud)
这种方法存在一个问题,它可能需要大量的线轴,当您省略时很容易看到WHERE rn = 1.
小智 6
SELECT ID,
TRIM(TRAILING ',' FROM (XMLAGG(TRIM(String)|| ',' ORDER BY String) (VARCHAR(10000)))) as Strings
FROM db.table
GROUP BY 1
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13111 次 |
| 最近记录: |