8

我正在使用 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

我试过分区,但可以有很多名字。我如何得到这个结果。甚至,给我指出正确的方向会很棒。

4

3 回答 3

8

不幸的是,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.

于 2013-10-26T12:01:38.753 回答
6
SELECT ID,  
TRIM(TRAILING ',' FROM (XMLAGG(TRIM(String)|| ',' ORDER BY String) (VARCHAR(10000)))) as Strings
FROM db.table
GROUP BY 1  
于 2019-02-27T17:39:15.707 回答
0

SQL Server 2017+ 和 SQL Azure:STRING_AGG

从 SQL Server 的下一个版本开始,我们终于可以跨行连接,而无需求助于任何变量或 XML 巫术。

STRING_AGG (Transact-SQL)

SELECT ID, STRING_AGG(String, ', ') AS Strings
FROM TableName
GROUP BY ID
于 2021-04-16T12:09:44.117 回答