Я пытаюсь получить количество клиентов ежедневно для каждого статуса в динамическом окне c - последние 30 дней. В результате запроса каждый день должно отображаться количество клиентов на каждый статус клиента (A, B, C) за последние 30 дней (т. Е. Сегодня () - 29 дней). Каждый клиент может иметь один статус за раз, но при переходе от одного статуса к другому. Цель этого запроса - показать «движение» клиента на протяжении всей его жизни. Я сгенерировал серию дат, начиная с первой даты, когда клиент был создан, до сегодняшнего дня.
Я собрал следующий запрос, но кажется, что что-то, что я делаю, неверно, потому что результаты отображают большинство дней с одинаковым количеством во всех статусах, что невозможно, каждый день создаются новые клиенты. Мы проверили с помощью другого простого запроса и подтвердили, что разделение между состояниями не равно.
Я попытался изобразить ниже данные и SQL, которые я использую для достижения оптимального результата.
Начальная точка (пример таблицы customer_statuses):
customer_id | status | created_at
---------------------------------------------------
abcdefg1234 B 2019-08-22
abcdefg1234 C 2019-01-17
...
abcdefg1234 A 2018-01-18
bcdefgh2232 A 2017-09-02
ghijklm4950 B 2018-06-06
статусы - A, B, C Нет последовательного заказа статусов, клиент может иметь любой статус в начале деловых отношений и переключаться между статусами в течение всей жизни.
таблица клиентов:
id | f_name | country | created_at |
---------------------------------------------------------------------
abcdefg1234 Michael FR 2018-01-18
bcdefgh2232 Sandy DE 2017-09-02
....
ghijklm4950 Daniel NL 2018-06-06
SQL - текущая версия:
WITH customer_list AS (
SELECT
DISTINCT a.id,
a.created_at
FROM
customers a
),
dates AS (
SELECT
generate_series(
MIN(DATE_TRUNC('day', created_at)::DATE),
MAX(DATE_TRUNC('day', now())::DATE),
'1d'
)::date AS day
FROM customers a
),
customer_statuses AS (
SELECT
customer_id,
status,
created_at,
ROW_NUMBER() OVER
(
PARTITION BY customer_id
ORDER BY created_at DESC
) col
FROM
customer_status
)
SELECT
day,
(
SELECT
COUNT(DISTINCT id) AS accounts
FROM customers
WHERE created_at::date BETWEEN day - 29 AND day
),
status
FROM dates d
LEFT JOIN customer_list cus
ON d.day = cus.created_at
LEFT JOIN customer_statuses cs
ON cus.id = cs.customer_id
WHERE
cs.col = 1
GROUP BY 1,3
ORDER BY 1 DESC,3 ASC
В настоящее время как выглядят результаты запроса:
day | count | status
-------------------------
2020-01-24 1230 C
2020-01-24 1230 B
2020-01-24 1230 A
2020-01-23 1200 C
2020-01-23 1200 B
2020-02-23 1200 A
2020-02-22 1150 C
2020-02-22 1150 B
...
2017-01-01 50 C
2017-01-01 50 B
2017-01-01 50 A
Две вещи, которые я заметил из приведенных выше результатов - в большинстве случаев результаты показывают одинаковое количество для всех статусов в данный день. Второе наблюдение, есть дни, когда появляются только два статуса - что не должно иметь место. Если в данный день создаются новые учетные записи с определенным статусом, счет предыдущего дня следует перенести - верно? или это проблема с запросом, который я создал, или с логи c, которые я имею в виду ?? Возможно, я ожидаю результата, который не будет логически получен?
Требуемый результат:
day | count | status
-------------------------
2020-01-24 1230 C
2020-01-24 1000 B
2020-01-24 2500 A
2020-01-23 1200 C
2020-01-23 1050 B
2020-02-23 2450 A
2020-02-22 1160 C
2020-02-22 1020 B
2020-02-22 2400 A
...
2017-01-01 10 C
2017-01-01 4 B
2017-01-01 50 A
Спасибо!