Teradata SQL连接多行
我使用的是Teradata,我有一个这样的表Teradata SQL连接多行,teradata,concat,partition,Teradata,Concat,Partition,我使用的是Teradata,我有一个这样的表 ID String 123 Jim 123 John 123 Jane 321 Jill 321 Janine 321 Johan 我想查询表,以便 ID String 123 Jim, John, Jane 321 Jill, Janine, Johan 我尝试了分区,但可以有许多名称。 我如何得到这个结果。甚至,给我指出正确的方向也很好 不
ID String
123 Jim
123 John
123 Jane
321 Jill
321 Janine
321 Johan
我想查询表,以便
ID String
123 Jim, John, Jane
321 Jill, Janine, Johan
我尝试了分区,但可以有许多名称。
我如何得到这个结果。甚至,给我指出正确的方向也很好 不幸的是,Teradata中没有轴心(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;
对于大型表,首先使用GROUPBY列作为PI在易失性表中具体化派生表的结果时,效率要高得多
对于递归,您也应该使用Volatile表,因为在递归部分不允许使用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;
这种方法有一个问题,当您省略
其中rn=1
SQL Server 2017+和SQL Azure:STRING\u AGG时,可能需要大量的假脱机文件,这很容易看到
SELECT ID,
TRIM(TRAILING ',' FROM (XMLAGG(TRIM(String)|| ',' ORDER BY String) (VARCHAR(10000)))) as Strings
FROM db.table
GROUP BY 1
从SQL Server的下一个版本开始,我们最终可以跨行连接,而无需借助任何变量或XML巫术
SELECT ID, STRING_AGG(String, ', ') AS Strings
FROM TableName
GROUP BY ID