简体   繁体   中英

Calculate Remaining Total by Record in Oracle Using LAG Window Function

I am having difficulty using the LAG window function to make what I can best describe as a ledger with a running total using Oracle 12. I have abstracted the problem like this:

I have an airliner with a fixed number of seats, but sometimes the flight is oversold. I am trying to figure out who gets a ticket and who doesn't by using a running total.

For each passenger (PASS), I have ordered the data by the class (1=1st class, 2=economy) and the priority (who ordered first) within it.

In the REM column, I am trying to get a running total of how many seats are left. I assume that each PASS will take up only one seat, and I have a fixed number of AVAIL seats per class. The seats remaining after that passenger is seated (REM) will decrease by one per user in the partition. The desired result would look like:

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

I have been trying to do this:

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

But my final data for REM has been coming out wrong:

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

I'm obviously approaching this wrong with my window function because it is looking for the next AVAIL record in the partition and subtracting one, but AVAIL doesn't change and so I get the same value for REM across the partition.

How do I get REM to subtract 1 from AVAIL in the partition and then use that new value for AVAIL in the next row?

This seems to match your description:

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

Available seats minus the cumulative count of rows per class.

And a cumulative count is equal to a ROW_NUMBER:

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

Just subtract the running sum from avail column.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM