【问题标题】:Case when with aggregation in BigQuery在 BigQuery 中使用聚合的情况
【发布时间】:2021-07-12 23:02:19
【问题描述】:

我有用户在 BigQuery 中的几款游戏中花费的数据:

CREATE TABLE if not EXISTS user_values (
  user_id int,
  value float,
  game char
);

INSERT INTO user_values VALUES
(1, 10, 'A'),
(1, 10, 'A'),
(1, 2, 'A'),
(1, 4, 'B'),
(1, 5, 'B'),
(2, 0, 'A'),
(2, 10, 'B'),
(2, 6, 'B');

我想检查每个用户在游戏 A 中的花费是否超过 20,在游戏 B 中是否超过 15。在这种情况下,输出表应该是:

user_id,game,spent_more_than_cutoff
1,A,TRUE
1,B,FALSE
2,A,FALSE
2,B,TRUE

我想为任意数量的用户和 5-10 个游戏执行此操作。我试过这个:

    select
        game,
        user_id,
        case
            when sum(value) > 20 and game = 'A' then TRUE
            when sum(value) > 15 and game = 'B' then TRUE
            else FALSE
        end as spent_more_than_cutoff,
    from user_values
    group by 1, 2

但我得到以下错误:

第 3 列包含一个聚合函数,该函数在 [19:20] 的 GROUP BY 中是不允许的

在 BigQuery 中无需针对不同游戏执行不同查询的最简单方法是什么?

有没有all 函数可以帮助做这样的事情?

    select
        game,
        user_id,
        case
            when sum(value) > 20 and all(game) = 'A' then TRUE
            when sum(value) > 15 and all(game) = 'B' then TRUE
            else FALSE
        end as spent_more_than_cutoff,
    from user_values
    group by 1, 2

【问题讨论】:

    标签: sql google-bigquery


    【解决方案1】:

    我想为任意数量的用户和 5-10 款游戏执行此操作

    考虑以下方法

    with cutoffs as (
      select 'A' game, 20 cutoff union all 
      select 'B', 15
    )
    select user_id, game, 
      sum(value) > any_value(cutoff) spent_more_than_cutoff
    from user_values
    left join cutoffs using(game)
    group by user_id, game    
    

    如果在您的问题中应用于user_values 的样本数据 - 输出是

    【讨论】:

      【解决方案2】:

      game 上的过滤表达式需要是sum()参数

      select game, user_id,
             (sum(case when game = 'A' then value end) > 20 and
              sum(case when game = 'B' then value end) > 15 
             ) as spent_more_than_cutoff
      from user_values
      group by 1, 2;
      

      请注意,您返回的是布尔值,因此不需要 case

      【讨论】:

      • @DavidMasip 。 . .这不符合您的要求吗?这似乎是最简单的解决方案。
      【解决方案3】:

      试试这个:

      select game,
             user_id,
             sum(if(game = 'A', value, 0)) > 20 or sum(if(game = 'B', value, 0)) > 15 as spent_more_than_cutoff
      from user_values
      group by 1, 2;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-06-12
        • 2021-01-02
        • 1970-01-01
        • 2013-05-16
        • 2013-01-11
        • 2016-04-26
        • 2013-05-06
        • 1970-01-01
        相关资源
        最近更新 更多