У меня есть файл CSV с четырьмя столбцами: дата, оптовый продавец, продукт и продажи.
Я ищу среднее значение продаж за последние 52 недели для каждой комбинации продукта и оптовика на каждую дату. Это означает, каковы были средние предыдущие продажи продукта A у оптовика B в момент времени C за последние 52 недели.
Например, мы знаем, что продажи продукта «А» у оптовика «Б» в январе, апреле, мае, августе составляют 100, 200, 300, 400 соответственно. Предположим, у нас нет никаких записей до января. Таким образом, среднее значение предыдущей продажи продукта «А» оптовому торговцу «В» в апреле равно 100/1, а в мае равно (200 + 100) / 2 и в августе (300 + 200 + 100) / 3.
Следующая таблица показывает мои данные:
date wholesaler product sales
12/31/2012 53929 UPE54 4
12/31/2012 13131 UPE55 1
2/23/2013 13131 UPE55 1156
4/24/2013 13131 UPE55 1
12/1/2013 83389 UPE54 9
12/17/2013 83389 UPE54 1
12/18/2013 52237 UPE54 9
12/19/2013 53929 UME24 1
12/31/2013 82204 UPE55 9
12/31/2013 11209 UME24 4
12/31/2013 52237 UPE54 1
Теперь я использую код Python, который правильно работает только с небольшими базами данных. Поскольку в моем наборе данных более 25 миллионов строк, я ищу лучший способ найти решение. Большое спасибо за вашу помощь!
2 ответа
Я думаю, это то, что вы ищете.
WITH cte_prep
AS (
SELECT
YEAR(date) * 100 + DATEPART(WEEK, [DATE]) AS week
, date
, RANK() OVER ( PARTITION BY product, wholesaler ORDER BY YEAR(date) * 100 + DATEPART(WEEK, [DATE]) ) AS product_wholesaler_week_rank
, [wholesaler]
, [product]
, [sales]
FROM
[meta].[dbo].[sales]
)
SELECT
CW.wholesaler
, CW.product
, CW.week
, CW.product_wholesaler_week_rank
, CW.sales
, AVG(BW.sales) AS avg_sales
FROM
cte_prep AS CW
INNER JOIN cte_prep BW
ON BW.product = CW.product AND
BW.wholesaler = CW.wholesaler AND
CW.product_wholesaler_week_rank >= BW.product_wholesaler_week_rank
AND BW.product_wholesaler_week_rank >= CW.product_wholesaler_week_rank - 52
GROUP BY
CW.wholesaler
, CW.product
, CW.week
, CW.sales
, CW.product_wholesaler_week_rank
ORDER BY
CW.wholesaler
, CW.product
, CW.week desc
select sum('sales')/count('sales')
from table
Group by year(date)
То, о чем вы просите, немного сложнее, чем ответ, который я дал. Я дал ответ, который работает, если вы хотите сгруппировать периоды продолжительностью в год только с 1 января по 31 декабря. Возможно, вам нужны периоды продолжительностью в год, но, возможно, вы захотите их с 1 июля по 30 июня.
Чтобы сделать это, найдите способы группировки по диапазонам дат. Вот несколько ссылок, которые могут оказаться полезными.
https://dba.stackexchange.com/questions/59356/grouping-by-date-range-in-a-column
Как в SQL можно «группировать по» по диапазонам?
Похожие вопросы
Связанные вопросы
Новые вопросы
sql
Язык структурированных запросов (SQL) - это язык запросов к базам данных. Вопросы должны включать примеры кода, структуру таблицы, примеры данных и тег для используемой реализации СУБД (например, MySQL, PostgreSQL, Oracle, MS SQL Server, IBM DB2 и т. Д.). Если ваш вопрос относится исключительно к конкретной СУБД (использует определенные расширения / функции), используйте вместо этого тег этой СУБД. Ответы на вопросы, помеченные SQL, должны использовать стандарт ISO / IEC SQL.