【问题标题】:Best way to by column and aggregation on another column在另一列上按列和聚合的最佳方法
【发布时间】:2018-11-07 04:05:54
【问题描述】:

我想使用现有的排名和二进制列创建排名列。例如,假设一个具有 ID、RISK、CONTACT、DATE 的表。现有的等级是 RISK,比如 1,2,3,NULL,其中 3 是最高的。二进制值是带有 0,1 或 FAILURE/SUCESS 的 CONTACT。我想创建一个新的 RANK,一旦超过一定数量的成功联系,它将按 RISK 排序。

例如,假设约束条件是至少 2 次成功联系。那么排名应该在下面的两个实例中创建如下:

实例 1. 三个 ID,都至少有两个成功的联系人。在这种情况下,排名反映了风险:

ID  risk  contact  date  rank
1   3     S        1     3
1   3     S        2     3
1   3     F        3     3
1   3     F        4     3
2   2     S        1     2
2   2     S        2     2
2   2     F        3     2
2   2     F        4     2
3   1     S        1     1
3   1     S        2     1
3   1     S        3     1

实例 2。假设 ID=1 只有一个成功的联系。在这种情况下,它被降级为最低等级,等级=1,而 ID=2 获得最高值,等级=3,并且 ID=3 映射到等级=2,因为它满足约束但风险值低于 ID =2:

ID  risk  contact  date  rank
1   3     S        1     1
1   3     F        2     1
1   3     F        3     1
1   3     F        4     1
2   2     S        1     3
2   2     S        2     3
2   2     F        3     3
2   2     F        4     3
3   1     S        1     2
3   1     S        2     2
3   1     S        3     2

这是 SQL,特别是 Hive。提前致谢。

编辑 - 我认为 Gordon Linoff 的代码是正确的。最后,我使用了三个临时表。代码如下:

首先,

--numerize risk, contact
select A.* ,
       case when A.risk = 'H' then 3
            when A.risk = 'M' then 2
            when A.risk = 'L' then 1
            when A.risk is NULL then NULL
            when A.risk = 'NULL' then NULL
       else -999 end as RISK_RANK,
       case when A.contact = 'Successful' then 1
       else NULL end as success

第二,

-- sum_successes_by_risk
select A.* ,
       B.sum_successes_by_risk
from T  as A 
inner join 
(select A.person, A.program, A.risk, sum(a.success) as sum_successes_by_risk
 from T as A
 group by A.person, A.program, A.risk
 ) as B
on A.program = B.program 
 and A.person = B.person
 and A.risk = B.risk

第三,

--Create table that contains only max risk category
select A.* ,
       B.max_risk_rank
from T as A 
inner join 
(select A.person, max(A.risk_rank) as max_risk_rank
 from T as A
 group by A.person
 ) as B
on A.person = B.person
   and A.risk_rank = B.max_risk_rank

【问题讨论】:

    标签: sql hive


    【解决方案1】:

    这很难理解,但我认为您只需要窗口函数:

    select t.*,
           (case when sum(case when contact = 'S' then 1 else 0 end) over (partition by id) >= 2
                 then risk
                 else 1
            end) as new_risk
    from t;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-06
      • 1970-01-01
      • 1970-01-01
      • 2020-05-08
      • 1970-01-01
      • 2016-11-22
      • 2018-06-02
      • 2016-05-14
      相关资源
      最近更新 更多