sql - 如何从每组的前一行获取列值?

标签 sql postgresql

我会尽量正确地解释问题:

我有一个这样的表:

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_productid_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,因此如果这个查询是正确的,我不能使用它,因为它太慢了。

有人知道如何解决我的问题吗?

更新:

预期结果:

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

prev_sale_value 上的 null 值是因为该行是 (id_product, id_warehouse) 组中的第一行,但想法是直接用同一行的 sale_value 替换那个 null ,但是当我为每一行获得正确的 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

最佳答案

使用 lag 是正确的方法,但你的论点是错误的。正如您所说:

I want to get the sale_value of the previous row, but only if the previous row belongs to the same id_product and id_warehouse that the current row.

这意味着您的 partiton by 子句应包括 id_productid_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

关于sql - 如何从每组的前一行获取列值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21481094/

相关文章:

mysql - 根据mySQL中年的第一天将年,周转换为日期

python - 如何在 Django 中访问 table_name 变量?

sql - 如何简化嵌套SQL交叉连接?

java - 在 dropwizard 资源类中使用 jdbi sql 接口(interface)

python - 如何根据 postgresql 中的列值定义唯一约束?

python - sqlalchemy postgresql "Is Null"索引

python - csv中的 "Inf"是什么意思?

sql - 如何对 SQL 表中的连续时间戳进行分组?

java - 比较jpa中的时间戳列而不丢失微秒

mysql - 匹配所有值 "IN"sql查询