使用 LAG Window 函数在 Oracle 中按记录计算剩余总计
Posted
技术标签:
【中文标题】使用 LAG Window 函数在 Oracle 中按记录计算剩余总计【英文标题】:Calculate Remaining Total by Record in Oracle Using LAG Window Function 【发布时间】:2017-10-23 19:45:44 【问题描述】:我很难使用 LAG 窗口函数来制作我最能描述为使用 Oracle 12 的总账的分类账。我已将问题抽象如下:
我有一架固定座位数的客机,但有时航班超卖。我试图通过使用累计总数来确定谁得到了一张票,谁没有。
对于每位乘客 (PASS),我已按类别(1=1 等舱,2=经济舱)和其中的优先级(谁先下单)对数据进行排序。
在 REM 列中,我试图计算剩余的座位总数。我假设每张 PASS 只占一个座位,而且我每个班级都有固定数量的 AVAIL 座位。该乘客就座后剩余的座位 (REM) 将在分区中的每个用户减少一个。期望的结果如下所示:
PASS |PRI|CLASS|AVAIL|REM
User9 1 1 2 1
User1 4 1 2 0
User8 2 2 3 2
User4 3 2 3 1
User3 5 2 3 0
USER2 6 2 3 -1
我一直在尝试这样做:
SELECT
PASS, PRI, CLASS,
LAG(AVAIL, 1, AVAIL) OVER (PARTITION BY CLASS ORDER BY CLASS, PRI) - 1 AS REM
FROM TABLE
ORDER BY CLASS, PRI
但我的 REM 最终数据有误:
PASS |PRI|CLASS|AVAIL|REM
User9 1 1 2 1
User1 4 1 2 1
User8 2 2 3 2
User4 3 2 3 2
User3 5 2 3 2
USER2 6 2 3 2
我的窗口函数显然处理了这个错误,因为它在分区中寻找下一个 AVAIL 记录并减去一个,但 AVAIL 没有改变,所以我在整个分区中得到相同的 REM 值。
如何让 REM 从分区中的 AVAIL 中减去 1,然后在下一行中为 AVAIL 使用该新值?
【问题讨论】:
【参考方案1】:这似乎与您的描述相符:
AVAIL
- Count(*)
Over (PARTITION BY CLASS
ORDER BY PRI ROWS Unbounded Preceding)
可用座位减去每个班级的累积行数。
并且累积计数等于 ROW_NUMBER:
AVAIL
- ROW_NUMBER()
Over (PARTITION BY CLASS
ORDER BY PRI)
【讨论】:
明白了,谢谢!但是,为什么这行得通? @SandPiper:看看独立 ROW_NUMBER/COUNT 的结果。您的 LAG 方法不起作用,因为计算是基于上一行的 数据,而不是上一行的 计算结果。【参考方案2】:只需从avail
列中减去运行总和。
SELECT PASS, PRI, CLASS, AVAIL,
avail-sum(1) over(partition by class order by pri) AS REM
FROM TABLE
【讨论】:
虽然这个答案也有效,但我将另一个答案标记为已接受,因为我更容易将它从抽象中扩展回我的真实项目。谢谢!以上是关于使用 LAG Window 函数在 Oracle 中按记录计算剩余总计的主要内容,如果未能解决你的问题,请参考以下文章