SQL-агрегат Hive объединяет несколько sqls в один - PullRequest
0 голосов
/ 07 ноября 2019

У меня есть серийный sqls вроде:

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?

Ответы [ 2 ]

0 голосов
/ 07 ноября 2019

Похоже, вы пытаетесь вести кумулятивный подсчет, заключенный в скобки по часам. Для этого вы можете использовать оконную функцию, например:

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
;

Возможно, существует более простой способ, но в целом это должно дать правильный ответ.


Объяснение:

Используется 2 подзапроса для одного и того же ввода table, с производным полем с именем include, чтобы отслеживать, какие записи должны вносить вклад в итоговую сумму для каждого сегмента. Первый подзапрос просто берет все записи в таблице и присваивает 0 AS include. Второй подзапрос находит все уникальные name s и самый нижний слот hour, в которых появляется этот name, и присваивает им 1 AS include. 2 подзапроса LEFT JOIN 'редактируются вложенным запросом.

Самый внешний запрос делает COALESCE(M.include, 0) для заполнения любых NULL, созданных LEFT JOIN, и эти 1's и 0 s SUM 'ed и окном hour. Это должно быть SELECT DISTINCT вместо использования GROUP BY, потому что GROUP BY будет хотеть перечислить и hour и include, но в итоге каждая запись в данной группе hour будет свернута в одну строку(все еще с include=1). DISTINCT применяется после SUM, поэтому удаляет дубликаты, не удаляя входные строки.

0 голосов
/ 07 ноября 2019

Вы можете просто использовать оператор group by для вывода списка пользователей в соответствии со значением часа.

SELECT hour, count(distinct userId) 
    FROM tablename
GROUP BY hour
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...