2013-10-25 9 views
6

私はテラを使用しています、私はこの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があります(可能性は低いかもしれません)。

それ以外の場合は、再帰または集約の2つのオプションがあります。

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; 

あなたが最初のPIとしてのカラム、GROUP BYを使用して揮発性表に派生表の結果を実体化する場合には、はるかに効率的です。

再帰的な部分で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

これはちょうど私を大いに助けてくれました、ありがとうございます。 –

関連する問題