【问题标题】:Split array of values into rows in Amazon Redshift在 Amazon Redshift 中将值数组拆分为行
【发布时间】:2019-12-01 02:59:53
【问题描述】:

如何使用分隔符 (,) 将列中的值数组拆分为 Redshift 中的相应行?

输入数据:-

—————————————  
Empid | Items  
—————————————  
1001| A, B  
1002| B  
1003| C, D, E  

需要的输出:-

—————————————  
Empid | Items  
—————————————  
1001| A  
1001| B  
1002| B  
1003| C  
1003| D  
1003| E  

感谢任何帮助。

谢谢

【问题讨论】:

    标签: amazon-redshift


    【解决方案1】:

    在 redshift 中无法“功能性地”执行此操作。

    相反,你需要这样的东西

    select empid,'A' as items from input where items ilike 'A,'
    union all
    select empid,'B' as items from input where items ilike 'B,'
    union all
    select empid,'C' as items from input where items ilike 'C,'
    union all
    select empid,'D' as items from input where items ilike 'D,'
    union all
    select empid,'E' as items from input where items ilike 'E,'
    

    【讨论】:

      【解决方案2】:

      实际上,通过向 Redshift 添加存储过程,这是可能的

      下面的过程接受两个参数(source_tabletarget_table) 假设两个表都存在,它会转换问题中描述的数据

      它的工作方式是

      1. 逐行从源表中读取数据
      2. 找出项目列中的最大项目
      3. 在循环中提取每个项目
      4. 将 id + item 组合插入到目标表中
      CREATE OR REPLACE PROCEDURE Array_to_Rows(source_table VARCHAR, target_table VARCHAR) 
      LANGUAGE plpgsql
      AS $$
      DECLARE i INTEGER;
              rec RECORD;
              query VARCHAR;
              item VARCHAR;
              cnt INTEGER;
      BEGIN
          query := 'SELECT * FROM ' || source_table;
      
          FOR rec IN EXECUTE query
          LOOP
              select INTO cnt regexp_count(rec.items,',')+1;
              i := 1; 
      
              << items_loop >>
              LOOP
                  SELECT INTO item trim(split_part(rec.items,',',i));
                  EXECUTE 'INSERT INTO ' || target_table || ' values (' || rec.Empid || ',''' || item ||''')';
                  i := i + 1;
                  EXIT items_loop WHEN (i > cnt);
              END LOOP;  
          END LOOP;      
      END;
      $$
      

      用法:CALL Array_to_Rows('source table name','target table name')

      问题中的测试数据不到0.2秒,不知道OPs数据集有多大

      输出是

      Empid   item
      1001    A
      1001    B
      1002    B
      1003    C
      1003    D
      1003    E
      

      【讨论】:

        【解决方案3】:

        基于official docs,您可以使用JOIN

        假设您的输入是:

        —————————————  
        empid | items  
        —————————————  
        1001| [A, B]  
        1002| [B]  
        1003| [C, D, E]
        1004| []
        

        那么你可以这样做:

        SELECT t.empid, items as item
        FROM table_name AS t
            LEFT JOIN t.items AS items ON TRUE
        

        这将返回:

        —————————————  
        empid | item 
        —————————————  
        1001| A  
        1001| B  
        1002| B  
        1003| C  
        1003| D  
        1003| E
        1004| <NULL>  
        

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-07-07
        • 2012-12-18
        • 2022-01-14
        • 1970-01-01
        • 1970-01-01
        • 2017-09-20
        • 2013-08-07
        相关资源
        最近更新 更多