HIVEQL - 使用 NULL 值计算加权平均值 - 不使用 Coalesce

Posted

技术标签:

【中文标题】HIVEQL - 使用 NULL 值计算加权平均值 - 不使用 Coalesce【英文标题】:HIVEQL - Calculating weighted average with NULL values - without using Coalesce 【发布时间】:2021-10-14 09:35:19 【问题描述】:

已解决 - 使用以下逻辑清理数据

case when total_score_a IS NULL then 0 else unique_users_a end as unique_users_a

我希望根据用户数为多个值创建加权平均值 - 问题是某些条目的值可能为空。下表示例:

id value_a value_b value_c value_d user_count_a user_count_b user_count_c user_count_d
1 7 NULL 4 NULL 10 NULL 30 NULL
2 9 NULL NULL NULL 33 30 22 NULL
3 NULL 3 NULL 2 42 22 NULL 12

我需要合并列,否则我的加法和乘法将不起作用。这当然会将 NULLS 更改为 0 - 但是这会影响整体权重。让我用上表举个例子:

对于 ID:3 - Value_A 的值为 NULL,但对应的 user_count_a 有一个值。因此,如果我们合并并将 ID 3 的值 A 更改为 0,它将(错误地)包含在权重计算中。基本上我想要做的是跳过 NULL 值,即使有相应的 user_count 值。原因是此表中的值 a、b、c 和 d 代表用户反馈。如果它为 NULL,则表示没有给出反馈,因此即使我们有 user_count,将其作为 0 包含在权重中也是不正确的

这是我当前的查询:

select
id,
total_value_a,
user_count_a,
total_value_b,
user_count_b,
total_value_c,
user_count_c,
total_value_d,
user_count_d,
(total_wgt_user_calc/sum_of_users) as user_weighted_score,
hour
from(
  select
  id,
  total_value_a,
  user_count_a,
  total_value_b,
  user_count_b,
  total_value_c,
  user_count_c,
  total_value_d,
  user_count_d,
  (a_wgt_user_calc + b_wgt_user_calc + c_wgt_user_calc + d_wgt_user_calc) as total_wgt_user_calc,
  sum_of_users,
  hour
  from(
    select
    id,
    user_count_a,
    total_value_a,
    (total_value_a * user_count_a) as a_wgt_user_calc,
    user_count_b,
    total_value_b,
    (total_value_b * user_count_b) as b_wgt_user_calc,
    user_count_c,
    total_value_c,
    (total_value_c * user_count_c) as c_wgt_user_calc,
    user_count_d,
    total_value_d,
    (total_value_d * user_count_d) as d_wgt_user_calc,
    (user_count_a + user_count_b + user_count_c + user_count_d) as sum_of_users,
    hour
    from(
      select
      id,
      coalesce(user_count_a, 0) as user_count_a,
      coalesce(total_value_a, 0) as total_value_a,
      coalesce(user_count_b, 0) as user_count_b,
      coalesce(total_value_b, 0) as total_value_b,
      coalesce(user_count_c, 0) as user_count_c,
      coalesce(total_value_c, 0) as total_value_c,
      coalesce(user_count_d, 0) as user_count_d,
      coalesce(total_value_d, 0) as total_value_d,
      hour
      from overall_data)j)o)i;

我完全理解在 HIVE 中以这种方式执行的加法和乘法远非理想。但是,即使按照某些人的建议以这种方式使用 SUM:

SUM((a_wgt_user_calc) + SUM(b_wgt_user_calc) + SUM(c_wgt_user_calc) + SUM(d_wgt_user_calc)) as total_wgt_user_calc

如果不使用合并,我仍然会得到所有 NULLS。 我也许可以使用带有 IS NULL 的 case 语句,但不知道它的确切结构

非常感谢任何帮助!

TLDR:目前使用合并来允许加法和乘法运行。这具有包含不应包含的加权值的意外影响。需要找到一种方法让计算功能不合并。

【问题讨论】:

【参考方案1】:

为什么不将此表转换为更好的格式?

create table user_data as select id, value, user_count, value_type from 
   (select 
      id, 
      value_a as value, 
      user_count_a as user_count, 
      'A' as value_type 
    where 
      value_a is not NULL) 
UNION
    (select 
      id, 
      value_b as value, 
      user_count_b as user_count, 
      'A' as value_type 
    where 
      value_b is not NULL) 
UNION ...

这将使您能够就可能更易于使用的数据提出汇总问题。数据不会在 1 行中,但它确实避免了 case 语句。它可能会使数据更易于使用。

【讨论】:

感谢您的回复,因为在这种情况下需要 ID 的方式 - 总会有 NULL,因为我们需要一个复合表,其中每个 ID 一行包含来自每个类别的数据。因此,对于一个 ID,我们将拥有类别 A 的数据,而不是类别 B 的数据。通过在进入后续查询之前清理数据,我找到了一种解决方法。

以上是关于HIVEQL - 使用 NULL 值计算加权平均值 - 不使用 Coalesce的主要内容,如果未能解决你的问题,请参考以下文章

计算 A 加权和 C 加权值

SQL Server - 查询以根据每年的最后一个值计算加权平均值

在 Reporting Services 2008 中计算加权平均值

numpy/python 中的加权平均值

计算时间加权移动平均线

使用熊猫/数据框计算加权平均值