1

У меня есть таблица, полная цен, предметов и дат. Примером этого является:Функция агрегирования для получения разницы или отношения двух строк в порядке

AA, 1/2/3024, 1.22 
AA, 1/3/3024, 1.23 
BB, 1/2/3024, 4.22 
BB, 1/3/3024, 4.23 

Внутри данных есть только две строки за цену, и они упорядочены по дате. Как я могу сконденсировать этот набор данных в одну строку продукта, показывая разницу от последней цены до предыдущей? [Также это относится к коэффициенту, поэтому AA будет производить 1,23/1,22].

Результат должен выглядеть

AA, todays price-yesterdays price 

Несмотря на то функция сумма, нет функции вычитания по списку.

Я использую postgres 9.1.

ответ

2
select product, 
     sales_date, 
     current_price - prev_price as diff 
from (
    select product, 
     sales_date, 
     price as current_price, 
     lag(price) over (partition by product order by sales_date) as prev_price, 
     row_number() over (partition by product order by sales_date desc) as rn 
    from the_unknown_table 
) t 
where rn = 1; 

SQLFiddle пример: http://sqlfiddle.com/#!15/9f7d6/1

+0

Thats awesome! Сегодня я узнал о SQL Fiddle. – monksy

+0

Мне потребовалось некоторое время, чтобы понять, для чего нужен номер строки, но теперь я понимаю – monksy

+0

Третий комментарий .. но это довольно умно об использовании порядка и порядка по desc. Сначала я подумал, что это была ошибка. – monksy

0

Если есть только две строки за единицу, затем

SELECT item, MAX(price) - MIN(price) AS diff, MAX(price)/MIN(price) AS ratio 
FROM yourtable 
GROUP BY item 

будет делать трюк.

+0

Это не будет работать, потому что разница должна основываться на дате. Ака сегодняшняя цена - вчерашняя цена. – monksy

2

С there are only two rows per price, это может быть гораздо проще и быстрее:

SELECT n.item, n.price - o.price AS diff, n.price/o.price AS ratio 
FROM price n     -- "new" 
JOIN price o USING (item) -- "old" 
WHERE n.day > o.day; 

->SQLfiddle

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


Для более сложных сценариев (не обязательно для этого), вы можете использовать окно функции, как было указано. Ниже приведен более простой подход, чем предложенный вариант:

SELECT DISTINCT ON (item) 
     item 
     ,price - lead(price) OVER (PARTITION BY item ORDER BY day DESC) AS diff 
FROM price 
ORDER BY item, day DESC; 

Здесь требуется только одна функция окна. И один уровень запроса, начиная с DISTINCT ON применяется после функции окна. Порядок сортировки в окне согласуется с общим порядком сортировки, что помогает производительности.

 Смежные вопросы

  • Нет связанных вопросов^_^