#sql #amazon-redshift
#sql #amazon-redshift
Вопрос:
Я хочу вычислить среднемесячное значение некоторых данных, используя SQL-запрос, где данные хранятся в redshift DB. Данные представлены в таблице в следующем формате.
s_date | sales
------------ -------
2020-08-04 | 10
2020-08-05 | 20
---- | --
---- | --
Данные могут отсутствовать за все даты месяца. Если данные отсутствуют в течение дня, их следует считать равными 0.
Следующий запрос с использованием функции AVG () «группировать по» месяцам as выдает среднее значение на основе данных на доступную дату.
select trunc(date_trunc('MONTH', s_date)::timestamp) as month, avg(sales) from sales group by month;
Однако он не учитывает данные для отсутствующих дат как 0. Каким должен быть правильный запрос для вычисления среднемесячного значения, как ожидалось?
Еще одно ожидание состоит в том, что за текущий месяц среднее значение должно быть рассчитано на основе данных по состоянию на сегодняшний день. Таким образом, он не должен учитывать весь месяц (например, 30 или 31 день).
С уважением,
Пол
Ответ №1:
Использование таблицы календаря может быть самым простым способом здесь:
WITH dates AS (
SELECT date_trunc('day', t)::date AS dt
FROM generate_series('2020-01-01'::timestamp, '2020-12-31'::timestamp, '1 day'::interval) t
),
cte AS (
SELECT t.dt, COALESCE(SUM(s.sales), 0) AS sales
FROM dates t
LEFT JOIN sales s ON t.dt = s.s_date
GROUP BY t.dt
)
SELECT
LEFT(dt::text, 7) AS ym,
AVG(sales) AS avg_sales
FROM cte
GROUP BY
LEFT(dt::text, 7);
Логика здесь заключается в том, чтобы сначала сгенерировать промежуточную таблицу во втором CTE, которая содержит по одной записи для каждой информации в вашем наборе данных, а также общий объем продаж на эту дату. Затем мы агрегируем по годам / месяцам и сообщаем о средних продажах.
Комментарии:
1. функция generate_series() не работает, поскольку данные находятся в красном смещении. Поэтому пришлось сгенерировать ряд дат другим способом. Однако приведенная здесь логика сработала.
2. @Paul Усвоенный урок: не помечайте не ту базу данных. Единственная часть, которую нужно было бы изменить, — это даты CTE. Найдите, как создавать календарные таблицы в Redshift.
3. Я выяснил, как генерировать даты CTE. Что касается тега, намерение состояло в том, чтобы получить логику либо в Redshift, либо в Postgres. Если логика понятна, то, я думаю, нетрудно реализовать то же самое в redshift. Ваш ответ является примером.
4. @Paul Просто для информации, Redshift основан на каком-то форке старой версии Postgres, отсюда и причина, по которой большинство (но не все) моих ответов на Postgres уже работали.
5. @Paul . . . Вы приняли ответ, который на самом деле не отвечает на вопрос. Возможно, вы захотите вернуть тег этого вопроса в Postgres и задать новый вопрос.