如何在 AWS Redshift 数据库中获取过滤器和分组依据子句的子字符串

Posted

技术标签:

【中文标题】如何在 AWS Redshift 数据库中获取过滤器和分组依据子句的子字符串【英文标题】:How to get substring for filter and group by clause in AWS Redshift database 【发布时间】:2018-04-24 06:37:30 【问题描述】:

如何从包含 AWS Redshift 数据库中过滤器和分组依据子句记录的列中获取子字符串。

我有如下记录的表格:

Table_Id | Categories         | Value
<ID>     | ABC1; ABC1-1; XYZ  | 10
<ID>     | ABC1; ABC1-2; XYZ  | 15
<ID>     | XYZ                | 5
.....

现在我想根据“ABC1”或“ABC1 和 XYZ”等单个类别过滤记录

查询的预期输出如下:

Table_Id | Categories         | Value
<ID>     | ABC1               | 25
<ID>     | ABC1-1             | 10
<ID>     | ABC1-2             | 15
<ID>     | XYZ                | 30
.....

因此需要根据各个类别对结果进行分组。

【问题讨论】:

输出中的聚合函数是什么?如果是总和,则 ABC1 不能为 15,因为 ABC1 在两行中,即 10+15 是的@AlexYes,它的错字。我更新了预期结果。实际上我想要各个类别的值。 【参考方案1】:

如果您在任何“类别”单元格中最多有 3 个值,您可以取消嵌套单元格,获取唯一值列表并在连接条件中使用该列表,如下所示:

WITH
values as (
    select distinct category
    from (
            select distinct split_part(categories,';',1) as category from your_table
            union select distinct split_part(categories,';',2) from your_table
            union select distinct split_part(categories,';',3) from your_table
     )
     where nullif(category,'') is not null
)
SELECT
 t2.category
,sum(t1.value)
FROM your_table t1
JOIN values t2
ON split_part(categories,';',1)=t2.category
OR split_part(categories,';',2)=t2.category
OR split_part(categories,';',3)=t2.category

如果您有超过 3 个选项,只需在 WITH 部分和连接条件中添加另一个 split_part 级别

【讨论】:

这是个好主意@Alexyes!我会更新我的答案,指出你的答案是最好的半动态选项。 谢谢@AlexYes。这似乎是一个很好的解决方案。我将更新您的解决方案以满足我的要求,因为我有未预定义大小的动态类别字符串(类别列表可能非常位于单独的行中)。完成查询后,我将更新我的答案。 @RaviPatel 你只需要知道尽可能多的选项并相应地更新,我想你可以接受这个答案【参考方案2】:

@JonScott、@AlexYes 和其他遇到类似情况的朋友。

我发现了比@AlexYes 建议的更好的方法。

我所做的是,我对生成单个记录的类别列进行了扁平化。 我可以进一步处理。

查询:

select row_number() over(order by 1) as r1, 
        to_char(timestamptz 'epoch' + date_time * interval '1 second', 'yyyy-mm-dd') AS DAY,
        split_part(categories, ';', numbers.n) as catg,
        value
    from <TABLE>
    join numbers
    on numbers.n <= regexp_count(category_string, ';') + 1 <OTHER_CONDITIONS>

说明:

这里有两个函数很有用:第一个是 split_part 函数,它接受一个字符串,将其拆分为 ';'分隔符,并返回从拆分字符串中指定的第一个、第二个、...、第 n 个值;其次,regexp_count,它告诉我们在字符串中找到特定模式的次数。

【讨论】:

看起来很棒!【参考方案3】:

要完全动态地执行此操作,您需要将“类别”列中的值转置或转置到单独的行中。 不幸的是,使用 redshift 无法实现“完全动态”的解决方案(事先不知道不同的值)。

您的选择如下:

    在另一个答案中使用 AlexYes 建议的方法。这是 半动态的,可能是您的最佳选择。

    在 Redshift 之外,运行一些 ETL 代码来执行 列 -> 多行 ETL。

    创建一个硬编码类型解决方案,并执行如下所示的枢轴:

    select table_id,'ABC1' as category, case when concat(Categories,';') ilike '%ABC1;%' then value else 0 end as value from your_table 联合所有 select table_id,'ABC1-1' as category, case when concat(Categories,';')ilike '%ABC1-1;%' then value else 0 end as value from your_table 联合所有

【讨论】:

以上是关于如何在 AWS Redshift 数据库中获取过滤器和分组依据子句的子字符串的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式:获取 AWS Redshift 中两个字符串之间的值

报告 AWS 工具 RDS 或 Redshift?

AWS 在 VPC 中访问 Redshift

将数据从 Athena 或 Redshift 获取到 Sage maker 或 AWS Forecast 而不是平面文件

获取过去 20 周三的数据:aws redshift

Redshift COPY 命令与 AWS 数据管道 RedshiftCopyActivity