【问题标题】:Split values over multiple rows in RedShift在 RedShift 中的多行上拆分值
【发布时间】:2015-07-07 09:47:47
【问题描述】:

如何将字段(例如 CSV 字符串)拆分为多行的问题已经得到解答: Split values over multiple rows.

但是,这个问题涉及 MSSQL,并且答案使用了没有 RedShift 等效项的各种功能。

为了完整起见,这是我想做的一个例子:

当前数据:

| Key | Data     |
+-----+----------+
| 1   | 18,20,22 |
| 2   | 17,19    |

所需数据:

| Key | Data     |
+-----+----------+
| 1   | 18       |
| 1   | 20       |
| 1   | 22       |
| 2   | 17       |
| 2   | 19       |

现在,对于 CSV 字段中元素数量有限且数量有限的情况,我可以建议一种解决方法:在所有可能的数组位置上使用 split_part 和 union,如下所示:

SELECT Key, split_part(Data, ',', 1) 
FROM mytable
WHERE split_part(Data, ',', 1) != ""
    UNION
SELECT Key, split_part(Data, ',', 2) 
FROM mytable
WHERE split_part(Data, ',', 2) != ""
-- etc. etc.

但是,这显然是非常低效的,并且不适用于更长的列表。

关于如何做到这一点的任何更好的想法?

编辑:

还有一个关于行乘法的类似问题:splitting rows in Redshift。但是我看不出如何在这里应用这种方法。

编辑2:

可能重复:Redshift. Convert comma delimited values into rows。但没有什么新鲜的 - @Masashi Miyazaki 的回答与我上面的建议相似,并且遇到了同样的问题。

【问题讨论】:

标签: sql split amazon-redshift


【解决方案1】:

这是 Redshift 的答案,每行最多可处理 10000 个值。

设置测试数据

create table test_data (key varchar(50),data varchar(max));
insert into test_data
    values
      (1,'18,20,22'),
      (2,'17,19')
;

代码

with ten_numbers as (select 1 as num union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9 union select 0)
  , generted_numbers AS
(
    SELECT (1000 * t1.num) + (100 * t2.num) + (10 * t3.num) + t4.num AS gen_num
    FROM ten_numbers AS t1
      JOIN ten_numbers AS t2 ON 1 = 1
      JOIN ten_numbers AS t3 ON 1 = 1
      JOIN ten_numbers AS t4 ON 1 = 1
)
  , splitter AS
(
    SELECT *
    FROM generted_numbers
    WHERE gen_num BETWEEN 1 AND (SELECT max(REGEXP_COUNT(data, '\\,') + 1)
                                 FROM test_data)
)
  , expanded_input AS
(
    SELECT
      key,
      split_part(data, ',', s.gen_num) AS data
    FROM test_data AS td
      JOIN splitter AS s ON 1 = 1
    WHERE split_part(data, ',', s.gen_num) <> ''
)
SELECT * FROM expanded_input
order by key,data;

【讨论】:

  • 我有类似的问题here 与拆分有关。我想看看你能不能帮帮我?
【解决方案2】:

欢迎您使用 RDS PostgreSql 实例并创建到 RedShift 的 dblink。然后,您可以像在普通 PostgreSQL 数据库上一样对结果集进行操作,甚至可以通过相同的 dblink 将结果放回 RedShift。

【讨论】:

  • redshift 不支持数组类型:docs.aws.amazon.com/redshift/latest/dg/…,所以这不是一个有效的答案...
  • 会非常高兴,但这是我得到的:“[Amazon](500310) 无效操作:Redshift 表不支持指定的类型或函数(每条 INFO 消息一个)。;警告: Function "string_to_array(text,text)" not supported" (查询: select string_to_array(csv_field, ',') from mytable;)
  • 集群版本为 1.0.901,允许版本升级...您有与此功能相关的文档吗(例如在 RedShift 的发行说明中?)
  • 对不起,我的错误。我建议使用的功能可以按照我仅建议的方式在 RedShift 上工作,并且不能按要求用于表数据。对表数据执行此操作的唯一方法是:获取 RDS PostgreSql 实例并创建到 RedShift 的 dblink。然后,您可以像在普通 PostgreSQL DB 上一样对结果集进行操作,甚至可以通过相同的 dblink 将结果放回 RedShift。
  • 谢谢@Yuri。这确实是一种可能的解决方法,但是它违背了使用 redshift 的最初目的(例如,对大量数据进行快速查询)。在这方面,问题中建议的方法可能会更好。似乎我们必须等待亚马逊会添加这个......
猜你喜欢
  • 1970-01-01
  • 2019-12-01
  • 1970-01-01
  • 2012-10-21
  • 1970-01-01
  • 2012-07-08
  • 1970-01-01
  • 2018-03-28
  • 1970-01-01
相关资源
最近更新 更多