Is it possible to group string within a string in Teradata?

后端 未结 1 422
无人共我
无人共我 2021-01-15 04:33

The original table (exactly the one that I am using .. with all commas brackets etc)

id     attributes
1      123(red), 139(red), 123(white), 123(black), 139         


        
1条回答
  •  抹茶落季
    2021-01-15 04:57

    SQL is definitely not the right language to do string processing like that :-)

    I used existing code to split/create comma-delimited strings, but in TD14 it would be much easier (there's strtok_split_to_table and udfConcat).

    CREATE VOLATILE TABLE vt (id INT, attrib VARCHAR(100)) ON COMMIT PRESERVE ROWS;
    
    INSERT INTO vt(1      ,'123(red), 139(red), 123(white), 123(black), 139(white),');
    INSERT INTO vt(2      ,'123(black), 139(white), 123(green),');
    INSERT INTO vt(32     ,'223(blue), 223(red), 553(white), 123(black),');
    INSERT INTO vt(4      ,'323(white), 139(red), ');
    INSERT INTO vt(23     ,'523(red),');
    
    WITH RECURSIVE cte
     (id,
      len,
      remaining,
      word,
      pos
     ) AS (
      SELECT
        id,
        POSITION(',' IN attrib || ',') - 1 AS len,
        SUBSTRING(attrib || ',' FROM len + 2) AS remaining,
        TRIM(SUBSTRING(attrib FROM 1 FOR len)) AS word,
        1
      FROM vt
      UNION ALL
      SELECT
        id,
        POSITION(',' IN remaining)- 1 AS len_new,
        SUBSTRING(remaining FROM len_new + 2),
        TRIM(SUBSTRING(remaining FROM 1 FOR len_new)),
        pos + 1
      FROM cte
      WHERE remaining <> ''
     )
    SELECT
      id,
         MAX(CASE WHEN newpos = 1 THEN newgrp ELSE '' END) ||
         MAX(CASE WHEN newpos = 2 THEN newgrp ELSE '' END) ||
         MAX(CASE WHEN newpos = 3 THEN newgrp ELSE '' END) ||
         MAX(CASE WHEN newpos = 4 THEN newgrp ELSE '' END) ||
         MAX(CASE WHEN newpos = 5 THEN newgrp ELSE '' END) ||
         MAX(CASE WHEN newpos = 6 THEN newgrp ELSE '' END)
         -- add as many CASEs as needed
    FROM
     ( 
       SELECT 
         id, 
         ROW_NUMBER() 
         OVER (PARTITION BY id
               ORDER BY newgrp) AS newpos,
         a ||
         MAX(CASE WHEN pos = 1 THEN '('  || b ELSE '' END) ||
         MAX(CASE WHEN pos = 2 THEN ', ' || b ELSE '' END) ||
         MAX(CASE WHEN pos = 3 THEN ', ' || b ELSE '' END) ||
         MAX(CASE WHEN pos = 4 THEN ', ' || b ELSE '' END) ||
         MAX(CASE WHEN pos = 5 THEN ', ' || b ELSE '' END) ||
         MAX(CASE WHEN pos = 6 THEN ', ' || b ELSE '' END)
         -- add as many CASEs as needed
         || '); ' AS newgrp
       FROM 
        (
          SELECT
            id,
            ROW_NUMBER() 
            OVER (PARTITION BY id, a
                  ORDER BY pos) AS pos,
            SUBSTRING(word FROM 1 FOR POSITION('(' IN word) - 1) AS a,
            TRIM(TRAILING ')' FROM SUBSTRING(word FROM POSITION('(' IN word) + 1)) AS b
          FROM cte
          WHERE word <> ''
        ) AS dt
       GROUP BY id, a
     ) AS dt
    GROUP BY id;
    

    0 讨论(0)
提交回复
热议问题