【问题标题】:Hive - max value across columns/multiple rowsHive - 跨列/多行的最大值
【发布时间】:2018-06-19 14:56:06
【问题描述】:

我的数据如下所示:

ip, category, a_score, b_score, c_score
1.2.3.4, X, 0, 5, 0
1.2.3.4, X, 3, 0, NULL
1.2.3.4, Y, 1, NULL, NULL
1.2.3.4, Y, 0, 2, 0
1.2.3.4, Z, 1, 0, 9
1.2.3.4, Z, 0, 2, 0

每个 IP 最多可以有 8 个类别和每个类别最多 3 个有效分数(a_score、b_score、c_score)。

对于每个 IP,我需要在该类别的所有分数中找到每个类别的最高分数。

所以在这种情况下,我会得到

1.2.3.4, X, 5
1.2.3.4, Y, 2
1.2.3.4, Z, 9

即,类别 X 的 a/b/c 分数的最大值是第一行的 c_score; Y 类的 a/b/c 分数的最大值是第二行的 b_score;类别 Z 的 a/b/c 分数的最大值是第一行的 c_score。

我试了一下

select ip, category, greatest(max(a_score), max(b_score), max(c_score)) from mytable where ip = '1.2.3.4' group by ip, category;

但这只会返回 NULL。

我该怎么做呢? TIA。

【问题讨论】:

    标签: sql hive


    【解决方案1】:

    将coalesce 与0(零)一起使用:

    select ip, category, 
         max(greatest(coalesce(a_score,0), coalesce(b_score,0), coalesce(c_score,0))) max_score
      from mytable 
     where ip = '1.2.3.4' 
    group by ip, category;
    

    Rextester Demo

    【讨论】:

    • 在您提供的演示链接中运行查询返回错误答案
    • @Craig 好的,我已经修好了。
    【解决方案2】:

    greatest() 的 NULL 值有问题,如您所见。对于您的情况,您可以执行以下操作:

    select ip, category,
           nullif(greatest(coalesce(max(a_score), -1), coalesce(max(b_score), -1), coalesce(max(c_score), -1)), -1)
    from mytable
    where ip = '1.2.3.4'
    group by ip, category;
    

    这假设分数永远不会是负数。

    另一种方法是在聚合之前取消透视。但是,这要么需要多次读取数据,要么需要复杂的case 表达式。

    【讨论】:

      猜你喜欢
      • 2023-04-06
      • 2019-02-11
      • 1970-01-01
      • 1970-01-01
      • 2018-12-16
      • 1970-01-01
      • 1970-01-01
      • 2021-04-03
      相关资源
      最近更新 更多