Количество продаж относительно исторической даты в предыдущем году - PullRequest
0 голосов
/ 06 июля 2018

У меня есть база данных, содержащая транзакции продаж. Они представлены в следующем (упрощенном) формате:

sales_id | customer_id | sales_date | number_of_units | total_price

Цель моего запроса - для каждой из этих транзакций получить количество продаж, которые этот конкретный customer_id совершил до текущей записи, за всю историю этой базы данных, но также и за 365 дней до текущей записи.

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

SELECT sales_id ,customer_id,sales_date,number_of_units,total_price,
    ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY sales_date ASC) as 'LifeTimeSales' ,
    CASE WHEN DATEDIFF(DAY,sales_date,LAG(sales_date, 1) OVER (PARTITION BY customer_id ORDER BY sales_date ASC)) > -365
         THEN 1 ELSE 0 END as 'Last365Sales'
 FROM sales_db

+ некоторые не важные пункты WHERE. После чего я агрегирую результат этого запроса некоторыми другими способами.

Но это не говорит мне, является ли эта покупка, например, 4-й продажей в предыдущие 365 дней покупателя.

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

Некоторые данные испытаний:

sales_id,customer_id,sales_date,number_of_units,total_price
1001,2001,2016-01-01,1,86
1002,2001,2016-08-01,3,98
1003,2001,2017-06-01,2,87
1004,2002,2017-06-01,2,15

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

sales_id,customer_id,sales_date,number_of_units,total_price,LifeTimeSales,Last365Sales
1001,2001,2016-01-01,1,86,0,0
1002,2001,2016-08-01,3,98,1,1
1003,2001,2017-06-01,2,87,2,1
1004,2002,2017-06-01,2,15,0,0

Ответы [ 2 ]

0 голосов
/ 06 июля 2018

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

with all_history_statistics as 
(select customer_id, sales_id, sales_date, number_of_units, total_price,
    max(sales_date) over (partition by customer_id order by (select null)) as last_sale_date,
    count(sales_id) over (partition by customer_id order by (select null)) total_number_of_sales,
    count(sales_id) over (partition by customer_id order by sales_date asc ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) number_of_sales_for_current_date,
    sum(number_of_units) over (partition by customer_id order by (select null)) total_number_saled_units,
    sum(number_of_units) over (partition by customer_id order by sales_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) number_saled_units_for_current_date,
    sum(total_price) over (partition by customer_id order by (select null)) as total_earned,
    sum(total_price) over (partition by customer_id order by sales_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) earned_for_current_date)
from sales_db),
with last_year_statistics as 
(select customer_id, sales_id, sales_date, number_of_units, total_price,
    max(sales_date) over (partition by customer_id order by (select null)) as last_sale_date,
    count(sales_id) over (partition by customer_id order by (select null)) total_number_of_sales,
    count(sales_id) over (partition by customer_id order by sales_date asc ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) number_of_sales_for_current_date,
    sum(number_of_units) over (partition by customer_id order by (select null)) total_number_saled_units,
    sum(number_of_units) over (partition by customer_id order by sales_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) number_saled_units_for_current_date,
    sum(total_price) over (partition by customer_id order by (select null)) as total_earned,
    sum(total_price) over (partition by customer_id order by sales_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) earned_for_current_date)
from sales_db)
select <specify list of fields which you need>
from all_history_statistics t1 inner join last_year_statistics
on t1.customer_id = t2.cutomer_id 
;
0 голосов
/ 06 июля 2018

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

SELECT s1.sales_id,
       s1.customer_id,
       s1.sales_date,
       s1.number_of_units,
       s1.total_price,
       (SELECT count(*)
               FROM sales_db s2
               WHERE s2.customer_id = s1.customer_id
                     AND s2.sales_date <= s1.sales_date) - 1 lifetimesales,
       (SELECT count(*)
               FROM sales_db s2
               WHERE s2.customer_id = s1.customer_id
                     AND s2.sales_date <= s1.sales_date
                     AND s2.sales_date >= dateadd(day, s1.sales_date, -356)) - 1 last365sales
       FROM sales_db s1;

(Я использовал s2.sales_date <= s1.sales_date, а затем вычел 1 из повторного расчета, так что несколько продаж в один и тот же день, если такие данные существуют, также учитываются. Но так как это также учитывает продажу текущей строки, необходимо быть уменьшено на 1.)

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