【问题标题】:Presto filter an array during aggregationPresto 在聚合期间过滤数组
【发布时间】:2021-01-04 22:14:03
【问题描述】:

我想根据与id 关联的所有值过滤聚合数组。值是字符串,可以是all-x:yx:y 和空三种类型(这里xy 是值的任意子字符串)。

我有几个条件:

  1. 如果id 具有x:y,则结果应包含x:y
  2. 如果id alwaysall-x:y,那么生成的聚合应该有all-x:y
  3. 如果id sometimesall-x:y,那么生成的聚合应该有x:y

例如下面的

WITH
 my_table(id, my_values) AS (
     VALUES
         (1, ['all-a','all-b']),
         (2, ['all-c','b']),
         (3, ['a','b','c']),
         (1, ['all-a']),
         (2, []),
         (3, ['all-c']),
),

结果应该是:

         (1, ['all-a','b']),
         (2, ['c','b']),
         (3, ['a','b','c']),

我已经为此工作了多个小时,但似乎不可行。

我想出了以下方法,但感觉它无法正常工作,因为我可以检查all-x 是否存在于<<IN ALL>> 中的所有数组中:

SELECT
    id,
    SET_UNION(
    CASE 
        WHEN SPLIT_PART(my_table.values,'-',1) = 'all' THEN 
            CASE 
                WHEN <<my_table.values IN ALL>> THEN my_table.values
                ELSE REPLACE(my_table.values,'all-')
            END 
        ELSE my_table.values
    END 
    ) AS values
FROM my_table
GROUP BY 1

我需要检查特定id 的所有数组values 是否包含all-x,这就是我努力寻找解决方案的地方。 我试图合作

经过几个小时的搜索,我开始相信这是不可行的。 任何帮助表示赞赏。感谢您的阅读。

【问题讨论】:

    标签: sql presto


    【解决方案1】:

    这应该做你想做的:

    WITH my_table(id, my_values) AS (
         VALUES
             (1, array['all-a','all-b']),
             (2, array['all-c','b']),
             (3, array['a','b','c']),
             (1, array['all-a']),
             (2, array[]),
             (3, array['all-c'])
    ),
    with_group_counts AS (
        SELECT *, count(*) OVER (PARTITION BY id) group_count  -- to see if the number of all-X occurrences match the number of rows for a given id
        FROM my_table
    ),
    normalized AS (
        SELECT
            id,
            if(
                count(*) OVER (PARTITION BY id, value) = group_count AND starts_with(value, 'all-'),  -- if its an all-X value and every original row for the given id contains it ...
                value,
                if(starts_with(value, 'all-'), substr(value, 5), value)) AS extracted
        FROM with_group_counts CROSS JOIN UNNEST(with_group_counts.my_values) t(value)
    )
    SELECT id, array_agg(DISTINCT extracted)
    FROM normalized
    GROUP BY id
    

    诀窍是通过with_group_counts 子查询中的count(*) OVER (PARTITION BY id) 表达式计算原始表中每个id 的总行数。然后,我们可以使用该值来确定是否应将给定值视为all-x 或应提取x。这由以下表达式处理:

    if(
        count(*) OVER (PARTITION BY id, value) = group_count AND starts_with(value, 'all-'),
        value,
        if(starts_with(value, 'all-'), substr(value, 5), value)) 
    

    有关 Presto 中窗口函数的更多信息,请查看documentation。你可以找到UNNESThere的文档。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-19
      • 2021-02-06
      • 2017-01-18
      • 2021-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-16
      相关资源
      最近更新 更多