Подсчет в динамическом диапазоне дат - PullRequest
0 голосов
/ 28 февраля 2019

У меня есть таблица с полями: customer_id, start_trial_date, end_trial_date.Я пытаюсь написать запрос, который можно использовать для подсчета customer_id s на определенную дату.

|+-------------+------------+------------+
| customer_id | start_date |  end_date  |
+-------------+------------+------------+
|           1 | 2017-02-03 | 2017-05-01 |
|           2 | 2017-04-07 | 2017-09-01 |
|           3 | 2017-03-02 | 2018-03-04 |
|           4 | 2013-02-25 | 2015-01-22 |
|           5 | 2015-11-10 | 2016-03-25 |
|     ....    |     ....   |     ....   |
+-------------+------------+------------+

Как мне написать запрос для получения набора результатов, в котором все даты находятся в диапазоне сколичество customer_id с, чей допустимый период включает эту дату?

Ожидаемый результат:

+------------+-----------+
|    date    | customers |
+------------+-----------+
| 2013-01-01 | 0         |
| ….         | ….        |
| 2017-04-20 | 3         |
| …..        | ….        |
| 2018-12-31 | ….        |
+------------+-----------+

Я использую BigQuery, если это имеет значение.Я рассмотрел создание вспомогательной таблицы, в которой перечислены все даты для диапазона, а затем попытался соединить ее с моей таблицей и сосчитать, но у меня нет подходящего ключа объединения в этом подходе.

Ответы [ 2 ]

0 голосов
/ 01 марта 2019

Ниже для BigQuery Standard SQL

#standardSQL
WITH calendar AS (
  SELECT day
  FROM (
    SELECT MIN(start_date) min_date, MAX(end_date) max_date
    FROM `project.dataset.table`
  ), UNNEST(GENERATE_DATE_ARRAY(min_date, max_date)) day
)
SELECT day, COUNTIF(day BETWEEN start_date AND end_date) customers
FROM calendar, `project.dataset.table`
GROUP BY day

Вы можете протестировать, поиграть с выше, используя фиктивные данные, как в примере ниже

#standardSQL
WITH `project.dataset.table` AS (
  SELECT 1 customer_id, DATE '2017-01-01' start_date, DATE '2017-01-05' end_date UNION ALL
  SELECT 2, '2017-01-03', '2017-01-04' UNION ALL
  SELECT 3, '2017-01-04', '2017-01-06' UNION ALL
  SELECT 4, '2017-01-10', '2017-01-12' UNION ALL
  SELECT 5, '2017-01-12', '2017-01-13' 
), calendar AS (
  SELECT day
  FROM (
    SELECT MIN(start_date) min_date, MAX(end_date) max_date
    FROM `project.dataset.table`
  ), UNNEST(GENERATE_DATE_ARRAY(min_date, max_date)) day
)
SELECT day, COUNTIF(day BETWEEN start_date AND end_date) customers
FROM calendar, `project.dataset.table`
GROUP BY day
-- ORDER BY day   

с результатом

Row day         customers    
1   2017-01-01  1    
2   2017-01-02  1    
3   2017-01-03  2    
4   2017-01-04  3    
5   2017-01-05  2    
6   2017-01-06  1    
7   2017-01-07  0    
8   2017-01-08  0    
9   2017-01-09  0    
10  2017-01-10  1    
11  2017-01-11  1    
12  2017-01-12  2    
13  2017-01-13  1    
0 голосов
/ 28 февраля 2019

Создание календарной таблицы является хорошей отправной точкой.После того, как у вас есть эта таблица (скажем, таблица calendar со столбцом calendar_date), вы можете использовать LEFT JOIN и агрегирование:

SELECT c.calendar_date, COUNT(t.customer_id) customers
FROM calendar c
LEFT JOIN mytable t 
    ON c.calendar_date >= t.start_date AND c.calendar_date <= t.end_date
GROUP BY c.calendar_date

Примечание: вы можете адаптировать условия неравенства (>= или >, <= или <) в соответствии с вашими точными требованиями.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...