使用LAG窗口函数

时间:2017-10-23 19:45:45

标签: sql oracle window-functions

我很难使用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值。 / p>

如何让REM从分区中的AVAIL中减去1,然后在下一行使用AVAIL的新值?

2 个答案:

答案 0 :(得分:2)

这似乎符合您的描述:

AVAIL 
- Count(*)
  Over (PARTITION BY CLASS 
        ORDER BY PRI ROWS Unbounded Preceding)

可用座位减去每个班级的累计行数。

累积计数等于ROW_NUMBER:

AVAIL 
- ROW_NUMBER()
  Over (PARTITION BY CLASS 
        ORDER BY PRI)

答案 1 :(得分:1)

只需从avail列中减去运行总和。

SELECT PASS, PRI, CLASS, AVAIL,
avail-sum(1) over(partition by class order by pri) AS REM
FROM TABLE