Используя psql, как вы получаете общую сумму за последние 3 дня, за каждый день? - PullRequest
0 голосов
/ 11 октября 2018

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

SELECT
 date
 school_id,
 item_id, 
 sum(price) as total_price
 FROM purchases
 GROUP BY school_id, item_id, date
 ORDER BY school_id, date

Будет возвращено что-то вроде

date         school_id  item_id   total_price
 2016-11-18 |      1   |      1   |        0.50
 2016-11-17 |      1   |      2   |        1.00
 2016-11-16 |      1   |      1   |        0.50
 2016-11-18 |      2   |      2   |        1.00
 2016-11-17 |      2   |      2   |        1.00
 2016-11-16 |      2   |      2   |        1.00

Мне нужна таблица, которая возвращает итоговую цену за последние 3 дня (включая день) каждого дня, так что-то вроде

 date         school_id  item_id   total_price
 2016-11-18 |      1   |      1   |        1.00
 2016-11-17 |      1   |      2   |        1.00
 2016-11-16 |      1   |      1   |        0.50
 2016-11-18 |      2   |      2   |        3.00
 2016-11-17 |      2   |      2   |        2.00
 2016-11-16 |      2   |      2   |        1.00

Я знаю, что могу использовать lag () OVER (PARTITION BY), но мне, возможно, придется делать это месяцами, а не 3 днями, и для настройки лага потребуется вечность.Я не совсем уверен, какой другой метод я могу использовать.Любое руководство?

Ответы [ 2 ]

0 голосов
/ 11 октября 2018

Один из подходов состоит в том, чтобы просто использовать коррелированный подзапрос в предложении select:

SELECT
    date,
    school_id,
    item_id, 
    (SELECT SUM(p2.price) FROM purchases p2
     WHERE p1.school_id = p2.school_id AND
           p2.date BETWEEN p1.date - INTERVAL '3 DAY' AND p1.date) AS total_price
FROM purchases p1
GROUP BY school_id, item_id, date
ORDER BY school_id, date DESC;

Демо

Другой подход будетЧтобы воспользоваться оконными функциями Postgres:

SELECT
    date,
    school_id,
    item_id, 
    SUM(price) OVER (PARTITION BY school_id
        ORDER BY date ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) AS total_price
FROM purchases p1
GROUP BY school_id, item_id, date
ORDER BY school_id, date DESC;

Демо

Оба генерируют этот вывод:

enter image description here

Обратите внимание, что мой вывод school_id=1 не соответствует вашему ожидаемому выводу, но я думаю, что ваши ожидаемые данные имеют опечатку.

0 голосов
/ 11 октября 2018

Простое ВНУТРЕННЕЕ СОЕДИНЕНИЕ сделало бы. Вы присоединяете таблицу к себе, когда школа и предмет совпадают, а диапазон дат составляет 3 дня

Обратите внимание, что это даст скользящее среднее за последние 3 дня,но похоже на ваш вопрос, так как вы хотите последовательных дней, без скачков

SELECT
 p1.date
 p1.school_id,
 p1.item_id, 
 SUM(p2.price) total_price_3_days

purchases p1
INNER JOIN purchases p2 ON p1.school_id = p2.school_id AND p1.item_id = p2.item_id AND p2.`date` BETWEEN DATE_SUB(p1.`date`, INTERVAL 3 DAY) AND p1.`date`
 GROUP BY p1.school_id, p1.item_id, p1.date
 ORDER BY p1.school_id, p1.date
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...