如何处理此字符串?

时间:2019-05-03 02:51:02

标签: sql amazon-web-services amazon-redshift

我在一张表中有一些结果,每个表的结果各不相同;代表我需要拆分的一列中的多个条目。

这是我的SQL及其结果:

    select REGEXP_COUNT(value,';') as cnt,
    description
    from mytable;
1   {Managed By|xBoss}{xBoss xBoss Number|X0910505569}{Time 
Requested|2009-04-15 20:47:11.0}{Time Arrived|2009-04-15 21:46:11.0};   
1   {Managed By|Modern Management}{xBoss Number|}{Time Requested|2009-04- 
16 14:01:29.0}{Time Arrived|2009-04-16 14:44:11.0}; 
2   {Managed By|xBoss}{xBoss Number|X091480092}{Time Requested|2009-05-28 
08:58:41.0}{Time Arrived|};{Managed By|Jims Allocation}{xBoss xBoss 
Number|}{Time Requested|}{Time Arrived|};   

所需的输出:

R1:
Managed By: xBoss
Time Requested:2009-10-19 07:53:45.0
Time Arrived: 2009-10-19 07:54:46.0

R2:
Managed By:Own Arrangements
Number: x5876523
Time Requested: 2009-10-19 07:57:46.0
Time Arrived:

R3:
Managed By: xBoss
Time Requested:2009-10-19 08:07:27.0
    select   
    SPLIT_PART(description, '}', 1), 
    SPLIT_PART(description, '}', 2), 
    SPLIT_PART(description, '}', 3), 
    SPLIT_PART(description, '}', 4), 
    SPLIT_PART(description, '}', 5) 
    as description_with_tag from mytable;

当计数为1时可以,但是说明中有多个;时,不会给出结果。

是否可以根据计数将其放入数组中?

2 个答案:

答案 0 :(得分:2)

首先,值得指出的是,这种格式的数据无法利用Redshift可以提供的所有好处。 Amazon Redshift是一个列式数据库,当数据存储在适当的列中时,可以提供出色的性能。但是,从文本字段中选择特定的文本总是效果不佳。

因此,我的主要建议是将数据预处理为正常的行和列,以便Redshift可以为您提供最佳功能。

但是,为回答您的问题,我建议您制作一个标量用户定义函数

CREATE FUNCTION f_extract_curly (s TEXT, key TEXT)
  RETURNS TEXT
STABLE
AS $$
  # List of items in {brackets}
  items = s[1:-1].split('}{')

  # Dictionary of Key|Value from items
  entries = {i.split('|')[0]: i.split('|')[1] for i in items}

  # Return desired value
  return entries.get(key, None)

$$ LANGUAGE plpythonu;

我用以下方式加载了示例数据:

CREATE TABLE foo (
    description TEXT
);

INSERT INTO foo values('{Managed By|xBoss}{xBoss xBoss Number|X0910505569}{Time Requested|2009-04-15 20:47:11.0}{Time Arrived|2009-04-15 21:46:11.0};');
INSERT INTO foo values('{Managed By|Modern Management}{xBoss Number|}{Time Requested|2009-04-16 14:01:29.0}{Time Arrived|2009-04-16 14:44:11.0};');
INSERT INTO foo values('{Managed By|xBoss}{xBoss Number|X091480092}{Time Requested|2009-05-28 08:58:41.0}{Time Arrived|};{Managed By|Jims Allocation}{xBoss xBoss Number|}{Time Requested|}{Time Arrived|};');

然后我用以下方法进行了测试:

SELECT
  f_extract_curly(description, 'Managed By'),
  f_extract_curly(description, 'Time Requested')
FROM foo

得到结果:

xBoss               2009-04-15 20:47:11.0
Modern Management   2009-04-16 14:01:29.0
xBoss   

它不知道如何处理具有两次指定相同字段(在之间使用分号)的行。您没有为我提供足够的示例输入和输出行来弄清楚在这种情况下您想要什么,但是请随意调整代码以符合您的要求。

答案 1 :(得分:0)

Redshift中没有数组数据类型。有2个选项:

1)首先用split_part ';',然后对第一个split_part输出的每个索引分别合并结果,然后用split_part'}'结果,最后得到您所需要的。

2)创建一个Python UDF并使用Python处理这些字符串。我猜这是针对您的用例的最佳解决方案。

3)在Redshift之外转换数据。从您的数据结构来看,在复制到Redshift之前处理它似乎要好得多,将数组取消嵌套到行中并将键从对象中提取到列中。