2013-10-25 67 views
6

我使用Teradata的,我有這樣的SQL連接多個行

ID  String 
123  Jim 
123  John 
123  Jane 
321  Jill 
321  Janine 
321  Johan 

表我要查詢的表,所以我得到

ID  String 
123  Jim, John, Jane 
321  Jill, Janine, Johan 

我想分區,但可以有很多名。 我如何得到這個結果。即使我指出正確的方向也很棒。

回答

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

+0

感謝您對我進行重定向 –

+0

這對我來說非常有幫助,謝謝。 –