【问题标题】:Calculate Remaining Total by Record in Oracle Using LAG Window Function使用 LAG Window 函数在 Oracle 中按记录计算剩余总计
【发布时间】: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 使用该新值?

【问题讨论】:

    标签: sql oracle window-functions


    【解决方案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
    

    【讨论】:

    • 虽然这个答案也有效,但我将另一个答案标记为已接受,因为我更容易将它从抽象中扩展回我的真实项目。谢谢!
    猜你喜欢
    • 2022-01-18
    • 2014-06-11
    • 1970-01-01
    • 1970-01-01
    • 2021-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-12
    相关资源
    最近更新 更多