Агрегирование данных, когда условия хранятся в другой таблице - PullRequest
0 голосов
/ 22 апреля 2020

У меня есть две таблицы. I для каждой пары даты и категории в таблице table2 . Я хочу рассчитать количество записей за прошлую неделю и две недели для этой категории, рассчитанных по этому дню.

table1

| DATE         |Category |
|--------------|---------|
|2018-10-01    |ABC1     |
|2018-10-03    |ABC1     |
|2018-10-05    |ABC2     |
|2018-10-07    |ABC1     |
|2018-10-08    |ABC1     |
|2018-10-11    |ABC2     |
|2018-10-16    |ABC1     |
|2018-10-19    |ABC2     |
|2018-10-20    |ABC1     |
|2018-10-22    |ABC2     |
|2018-10-30    |ABC1     |

table2

| Category     |DATE           |
|--------------|---------------|
|ABC1          |2018-10-30     |
|ABC2          |2018-10-24     |
|ABC1          |2018-10-23     |
|ABC2          |2018-10-21     |

Конечный результат должен выглядеть примерно так

| Category     |DATE           |past_week  | past_2_weeks  |
|--------------|---------------|-----------|---------------|
|ABC1          |2018-10-30     |1          |3              |
|ABC2          |2018-10-24     |1          |1              |
|ABC1          |2018-10-23     |2          |2              |
|ABC2          |2018-10-21     |1          |1              |

Я знаю это может быть достигнуто в SQL с использованием коррелированных встроенных подзапросов, но у улья такой возможности нет. Есть ли оптимизированный способ сделать это?

ПРИМЕЧАНИЕ Набор данных очень большой, например, таблица1 содержит более 500000 строк, а таблица2 - около 20000 строк. Также доступно много других категорий (~ 160). Я только хочу показать вам, как выглядят таблицы.

1 Ответ

1 голос
/ 22 апреля 2020

Вы также можете выполнять подзапросы в Hive.

В вашем примере я присоединяюсь к двум подзапросам.

WITH t AS(
SELECT t2.category AS category, t2.date AS date, COUNT(*) AS past_week
FROM table_dos t2
JOIN table_uno t1 ON(t2.category = t1.category)
WHERE t2.date >= t1.date AND
      CEIL(DATEDIFF(to_date(t2.date),to_date(t1.date)) / 7) <= 1
GROUP BY t2.category, t2.date)
SELECT t.category AS category, t.date AS date ,t.past_week AS past_week, t2.past_2_weeks AS past_2_weeks
FROM t
JOIN (SELECT t2.category AS category, t2.date AS date, COUNT(*) AS past_2_weeks
FROM table_dos t2
JOIN table_uno t1 ON(t2.category = t1.category)
WHERE t2.date >= t1.date AND
      CEIL(DATEDIFF(to_date(t2.date),to_date(t1.date)) / 7) <= 2
GROUP BY t2.category, t2.date) AS t2
ON(t.category = t2.category)
WHERE t.date = t2.date
ORDER BY category, date DESC;

ожидаемый результат с данными

+-----------+-------------+------------+---------------+--+
| category  |    date     | past_week  | past_2_weeks  |
+-----------+-------------+------------+---------------+--+
| ABC1      | 2018-10-30  | 1          | 3             |
| ABC1      | 2018-10-23  | 2          | 2             |
| ABC2      | 2018-10-24  | 2          | 3             |
| ABC2      | 2018-10-21  | 1          | 2             |
+-----------+-------------+------------+---------------+--+

Я надеюсь, что это может быть полезно или поможет вам решить вашу проблему.

С уважением.

...