#sql #postgresql #window-functions #sql-view
#sql #postgresql #окно-функции #sql-просмотр
Вопрос:
У меня есть таблица под названием Stocks, которая содержит дату, StocksID и цену. Таблица содержит данные о цене нескольких различных рыночных акций в 2018 году. Я хотел бы создать представление таблицы Stocks, в которой отображаются дата, StocksID, previous_price, цена и change_in_price. Previous_price означает цену той же акции за день до этого. У меня возникла проблема с получением previous_price без использования какой-либо встроенной функции.
Я попытался получить previous_price, получив цену с предыдущей даты, но я не знаю, как получить предыдущую дату.
Любая помощь приветствуется, спасибо!
Пример вывода:
Date | StocksID | prevprice | price | change
----------- ----------- ----------- ------- --------
2012-01-04 | 1 | 0.91 | 0.92 | 0.01
2012-01-05 | 1 | 0.92 | 0.91 | -0.01
2012-01-06 | 1 | 0.91 | 0.90 | -0.01
2012-01-09 | 1 | 0.90 | 0.89 | -0.01
Ответ №1:
Это выглядит как хороший вариант использования для оконной функции LAG()
Postgres, доступной с версии 9.4:
SELECT
s.*,
LAG(price) OVER(PARTITION BY s.stocksID ORDER BY s.date) previous_price,
price - LAG(price) OVER(ORDER BY s.date) change
FROM Stocks s
Это даст вам разницу с предыдущей ценой того же самого, stocksID
заказанного date
. Пожалуйста, обратите внимание, что, в зависимости от ваших данных, это может быть не цена предыдущего дня (если, например, у вас есть задержки в ряду дат).
Комментарии:
1. Я принял «Без функций» за это тоже, но если OP означает только пользовательские функции, тогда вы правы.
2. @TomC: да… Я не могу представить, почему OP не захотел бы использовать встроенные функции Postgres.
Ответ №2:
Вы можете сделать это с помощью self join и not exists.
p1 является текущим, p2 является предыдущим
select p1.*, p2.*
from price p1
left join price p2 on p2.StocksID=p1.StocksID and p2.Date<p1.Date
and not exists(
select * from price p3
where p3.StocksID=p1.StocksID and p3.Date<p1.Date
and p3.Date>p2.date
)