Используя PostgreSQL, как я могу подсчитать количество людей, открывших сообщение за предыдущие 30 дней с понедельника каждой недели? - PullRequest
1 голос
/ 06 марта 2020

Сценарий:
У меня есть таблица events_table, которая состоит из записей, которые вставляются веб-крюком на основе сообщений, отправляемых моим пользователям:

" column_name "(тип)
-" отметка времени "(отметка времени с часовым поясом)
-" имя пользователя "(varchar)
-" доставлено "(int)
-" действие "(int )

Пример данных:

|    time_stamp   | username | delivered | action |
|:----------------|:---------|:----------|:-------|
|1349733421.460000|  user1   |     1     |  null  |
|1549345346.460000|  user3   |     1     |   1    |
|1524544421.460000|  user1   |     1     |   1    |
|1345444421.570000|  user7   |     1     |  null  |
|1756756761.980000|  user9   |     1     |  null  |
|1234343421.460000|  user171 |     1     |   1    |
|1843455621.460000|  user5   |     1     |   1    |
|      ...        |   ...    |   ...     |  ...   |

По умолчанию столбец «поставлено» и 1, если доставлено . Столбец «action» по умолчанию равен нулю и равен 1, когда открыт .

Проблема:
Используя PostgreSQL, как подсчитать сумму лица, открывшие электронное письмо в предыдущие 30 дней с понедельника каждой недели?

Идеальные результаты запроса:

|      date       |   count   |
|:----------------|:----------|
|   02/24/2020    | 1,234,123 |
|   02/17/2020    |  234,123  |
|   02/10/2020    | 1,234,123 |
|   02/03/2020    |12,341,213 |
|      ...        |    ...    |

Моя попытка : Это мера того, что я пробовал, подсчитывает предыдущую неделю:

SELECT
  date_trunc('week', to_timestamp("time_stamp")) as date,
  count("username") as count,
  lag(count(1), 1) over (order by "date") as "count_previous_week"
FROM events_table
WHERE "delivered" = 1
     and "action" = 1
GROUP BY 1 order by 1 desc     

1 Ответ

0 голосов
/ 06 марта 2020

Это моя попытка написать этот запрос.

Сначала я получаю самые низкие и самые высокие даты из набора данных. Я добавляю 7 дней к самой высокой дате, чтобы убедиться, что я включаю данные до сегодняшнего дня.

Затем я запускаю generate_series для этих двух значений, установленных с интервалом в 7 дней, чтобы давать мне каждый отдельный понедельник между 2 балла (мы не можем полагаться только на понедельники в вашем наборе данных, если у нас пустая неделя)

Затем я просто запрашиваю и объединяю данные на основе нашего generate_series вывода.

select
    __weeks.week_begins,
    (
        select
            count(distinct "username")
        from
            events_table
        where
            to_timestamp("time_stamp")::date between week_begins - '30 days'::interval and week_begins
            and "delivered" = 1
            and "action" = 1
    )
from
    (
        select
            generate_series(_.min_date, _.max_date, '7 days'::interval)::date as week_begins
        from
            (
                select
                    min(date_trunc('week', to_timestamp("time_stamp"))::date) as min_date
                    max(date_trunc('week', to_timestamp("time_stamp"))::date) as max_date
                from
                    events_table
                where
                    "delivered" = 1
                    and "action" = 1
            ) as _
    ) as __weeks
order by
    __weeks.week_begins

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

...