【问题标题】:Hive SQL aggregate merge multiple sqls into oneHive SQL 聚合 将多个 sql 合并为一个
【发布时间】:2019-11-16 01:10:09
【问题描述】:

我有一个像这样的串行 sql:

select count(distinct userId) from table where hour >= 0 and hour <= 0;
select count(distinct userId) from table where hour >= 0 and hour <= 1;
select count(distinct userId) from table where hour >= 0 and hour <= 2;
...
select count(distinct userId) from table where hour >= 0 and hour <= 14;

有没有办法将它们合并到一个 sql 中?

【问题讨论】:

  • 操作时尝试用例

标签: hive hiveql


【解决方案1】:

您似乎正在尝试保持以小时为单位的累积计数。为此,您可以使用窗口函数,如下所示:

SELECT DISTINCT
  A.hour AS hour,
  SUM(COALESCE(M.include, 0)) OVER (ORDER BY A.hour) AS cumulative_count
FROM ( -- get all records, with 0 for include
  SELECT
    name,
    hour,
    0 AS include
  FROM
    table
  ) A
  LEFT JOIN
  ( -- get the record with lowest `hour` for each `name`, and 1 for include
    SELECT
      name,
      MIN(hour) AS hour,
      1 AS include
    FROM 
      table
    GROUP BY
      name
  ) M
  ON  M.name = A.name
  AND M.hour = A.hour
;

可能有一种更简单的方法,但这通常会产生正确的答案。


说明:

这对同一输入 table 使用 2 个子查询,并使用一个名为 include 的派生字段来跟踪哪些记录应占每个存储桶的最终总数。第一个子查询简单地获取表中的所有记录并分配0 AS include。第二个子查询查找所有唯一的names 和出现name 的最低hour 槽,并将它们分配给1 AS include。这 2 个子查询由封闭查询 LEFT JOIN'ed。

最外层的查询执行COALESCE(M.include, 0) 来填充由LEFT JOIN 生成的任何NULL,而那些1 和0 是SUM'ed 并由@ 窗口化987654336@。这需要是SELECT DISTINCT 而不是使用GROUP BY,因为GROUP BY 将同时列出hour 和include,但它最终会将给定hour 组中的每条记录折叠成一行(仍然是include=1)。 DISTINCT 在SUM 之后应用,因此它将删除重复项而不丢弃任何输入行。

【讨论】:

  • 这不是不同的计数
  • 不同的计数也不是相加的。所以 0 和 1 之间的不同小时计数 小时 0 的不同计数 + 小时的不同计数 = 1
  • 它应该是不同的用户 ID,而不是不同的小时 + 计数。如果同一用户在不同时间出现两次怎么办
  • @leftjoin 我更新了这个答案。这正是我认为 OP 所追求的结果,而且我认为它也能解决您的顾虑。
猜你喜欢
  • 1970-01-01
  • 2022-01-07
  • 2012-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多