2014-01-31 4 views
1

Пожалуйста, прочитайте вопрос, это не дубликат.Как получить значение столбца из предыдущей строки для каждой группы?

Я попытаюсь объяснить право проблемы:

У меня есть таблица вроде этого:

Table: stg_mov_salida 

id_movement | id_product | id_warehouse | movement_date | id_sale | sale_value | ... 
209338   54545   2   "2011-05-21" 163299  75.95 
209306   54545   2   "2011-06-05" 163267  75.95 
209347   54545   2   "2012-10-26" 163308  77.95 
209399   54545   3   "2011-01-22" 163360  79.95 
209302   54545   3   "2011-01-23" 163263  72.95 
209304   54545   3   "2011-01-24" 163265  72.95 

И я хочу, чтобы получить sale_value в предыдущей строке, но только если предыдущая строка принадлежит тем же id_product и id_warehouse, что и текущая строка.

Таблица stg_mov_salida является промежуточной таблицей по заказу:

id_product asc, id_warehouse asc, movement_date asc 

Как я уже читал на других вопросах (например, this или подобные), я попытался сделать это без успеха. Последний запрос (и ближе к моему решению) Я попытался это:

SELECT x2.*, 
    (SELECT x2.sale_value AS last_sale_value 
      FROM stg_mov_salida ms 
       WHERE x2.id_product = ms.id_product 
       AND x2.id_warehouse = ms.id_warehouse 
       AND x2.date_movement > ms.date_movement 
      ORDER BY ms.id_product asc, 
          ms.id_warehouse asc, 
          ms.date_movement asc 
      LIMIT 1) 
FROM stg_mov_salida x2 

Но этот запрос настолько медленно, что я никогда не видел его отделки, даже только для одного данного id_product, поэтому если запрос правильный, я не могу его использовать, потому что он слишком медленный.

Кто-нибудь знает, как решить мою проблему?

UPDATE:

Ожидаемый результат:

id_movement | id_product | id_ware | mov_date | id_sale | sale_value | prev_sale_value 
    209338  54545   2 "2011-05-21" 163299  75.95   null 
    209306  54545   2 "2011-06-05" 163267  75.95   75.95 
    209347  54545   2 "2012-10-26" 163308  77.95   75.95 
    209399  54545   3 "2011-01-22" 163360  79.95   null 
    209302  54545   3 "2011-01-23" 163263  72.95   79.95 
    209304  54545   3 "2011-01-24" 163265  72.95   72.95 

В null значения на prev_sale_value бы потому, что строка является первой в группе (id_product, id_warehouse), но идея состоит в том, чтобы заменить это null с sale_value той же строки напрямую, но я сделаю это, когда я получу правильный prev_sale_value для каждой строки.

Любая помощь будет оценена

Для легко ответ, вот SQLFiddle

Я попробовал этот запрос тоже, но это не работает должным образом:

select x2.*, 
lag(sale_value, 1) over (partition by sale_value 
           order by id_product asc, 
           id_warehouse asc, 
           date_movement asc) as last_sale_value 

from stg_mov_salida x2 
order by id_product asc, id_warehouse asc, date_movement asc 
+0

Что ожидаемый выход для примера таблицы, которые вы дали? –

+0

Обновленный вопрос с ожидаемым результатом. Если вам нужна дополнительная информация, не сомневайтесь, чтобы спросить! – carexcer

+0

Проверьте функцию 'lag()': http://www.postgresql.org/docs/current/static/tutorial-window.html –

ответ

1

Использование lag это правильный путь, но ваши аргументы неправильны. Как вы заявили:

Я хочу получить sale_value предыдущей строки, но только если предыдущая строка относится к тому же id_product и id_warehouse, что и текущая строка.

Это означает, что ваша статья partiton by должна включать id_product и id_warehouse:

select x2.*, 
lag(sale_value, 1) over (partition by id_product asc, id_warehouse asc 
         order by date_movement asc) as last_sale_value  
from stg_mov_salida x2 
order by id_product asc, id_warehouse asc, date_movement asc 
+0

Отлично! Только вы должны удалить 'sale_value' из' partition by' clause, и он отлично работает! Исправьте его для будущих посетителей;) Большое спасибо! – carexcer

+0

@carexcer arg, rigtht. Ошибка копирования-вставки - исправлена. Спасибо, что заметили. – Mureinik

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