我如何从第二列做 运行 总计
How do i do running totals from second column
我有如下数据集,
Lot Size Reported QTY Qty Balance
150 100
150 100
150 80
150 80
150 5
Qty Balance需要计算如下,
Row 1 = Lot Size - Reported Qty (row1) => 150-100 = 50
Row 2 = Reported Qty (row1) - Reported Qty(row2) => 100-100 =0
Row 3 = Reported Qty (row2) - Reported Qty(row3) => 100-80 =20
... till the last row
我的预期结果是
Lot Size Reported QTY Qty Balance
150 100 50
150 100 0
150 80 20
150 80 0
150 5 75
如何在查询中实现这一点?
你应该看看 LAG()
解析函数。有关该函数及其接受的参数的详细信息,请参阅 here(例如,我认为您需要在 lag() 函数 returns 空。)
一旦您确定了上一行的报告数量值,您就可以简单地减去它。当然,您将需要某种方式来确定行的顺序——您的样本数据似乎没有,因此数据库将无法确定哪一行是第一行,哪一行是最后一行。
例如
with sample_data (lot_size, reported_qty) as (SELECT 150, 100 FROM DUAL
UNION ALL SELECT 150, 100 FROM DUAL
UNION ALL SELECT 150, 80 FROM DUAL
UNION ALL SELECT 150, 80 FROM DUAL
UNION ALL SELECT 150, 5 FROM DUAL)
select lot_size,
reported_qty,
lag(reported_qty, 1, lot_size) over (order by null) - reported_qty diff
from sample_data;
LOT_SIZE REPORTED_QTY DIFF
---------- ------------ ----------
150 100 50
150 100 0
150 80 20
150 80 0
150 5 75
正如@Boneist 所建议的,您需要使用 LAG() OVER() 解析函数。
你只需要再做一个任务来处理第一行,这将是 NULL,使用 CASE 你可以让它工作。
测试用例
SQL> WITH data AS
2 ( SELECT t.*, lag(reported_qty) OVER(ORDER BY NULL) rn FROM t
3 )
4 SELECT lot_size,
5 reported_qty,
6 CASE
7 WHEN rn IS NULL
8 THEN lot_size - reported_qty
9 ELSE rn - reported_qty
10 END qty_balance
11 FROM data;
LOT_SIZE REPORTED_QTY QTY_BALANCE
---------- ------------ -----------
150 100 50
150 100 0
150 80 20
150 80 0
150 5 75
SQL>
Oracle 11g R2 架构设置:
CREATE TABLE lots ( Lot_Size, Reported_QTY ) AS
SELECT 150, 100 FROM DUAL
UNION ALL SELECT 150, 100 FROM DUAL
UNION ALL SELECT 150, 80 FROM DUAL
UNION ALL SELECT 150, 80 FROM DUAL
UNION ALL SELECT 150, 5 FROM DUAL;
查询 1:
SELECT Lot_Size,
Reported_QTY,
COALESCE( LAG( Reported_QTY ) OVER ( ORDER BY NULL ) - Reported_QTY,
Lot_Size - Reported_QTY ) AS Qty_Balance
FROM Lots
| LOT_SIZE | REPORTED_QTY | QTY_BALANCE |
|----------|--------------|-------------|
| 150 | 100 | 50 |
| 150 | 100 | 0 |
| 150 | 80 | 20 |
| 150 | 80 | 0 |
| 150 | 5 | 75 |
我有如下数据集,
Lot Size Reported QTY Qty Balance
150 100
150 100
150 80
150 80
150 5
Qty Balance需要计算如下,
Row 1 = Lot Size - Reported Qty (row1) => 150-100 = 50
Row 2 = Reported Qty (row1) - Reported Qty(row2) => 100-100 =0
Row 3 = Reported Qty (row2) - Reported Qty(row3) => 100-80 =20
... till the last row
我的预期结果是
Lot Size Reported QTY Qty Balance
150 100 50
150 100 0
150 80 20
150 80 0
150 5 75
如何在查询中实现这一点?
你应该看看 LAG()
解析函数。有关该函数及其接受的参数的详细信息,请参阅 here(例如,我认为您需要在 lag() 函数 returns 空。)
一旦您确定了上一行的报告数量值,您就可以简单地减去它。当然,您将需要某种方式来确定行的顺序——您的样本数据似乎没有,因此数据库将无法确定哪一行是第一行,哪一行是最后一行。
例如
with sample_data (lot_size, reported_qty) as (SELECT 150, 100 FROM DUAL
UNION ALL SELECT 150, 100 FROM DUAL
UNION ALL SELECT 150, 80 FROM DUAL
UNION ALL SELECT 150, 80 FROM DUAL
UNION ALL SELECT 150, 5 FROM DUAL)
select lot_size,
reported_qty,
lag(reported_qty, 1, lot_size) over (order by null) - reported_qty diff
from sample_data;
LOT_SIZE REPORTED_QTY DIFF
---------- ------------ ----------
150 100 50
150 100 0
150 80 20
150 80 0
150 5 75
正如@Boneist 所建议的,您需要使用 LAG() OVER() 解析函数。
你只需要再做一个任务来处理第一行,这将是 NULL,使用 CASE 你可以让它工作。
测试用例
SQL> WITH data AS
2 ( SELECT t.*, lag(reported_qty) OVER(ORDER BY NULL) rn FROM t
3 )
4 SELECT lot_size,
5 reported_qty,
6 CASE
7 WHEN rn IS NULL
8 THEN lot_size - reported_qty
9 ELSE rn - reported_qty
10 END qty_balance
11 FROM data;
LOT_SIZE REPORTED_QTY QTY_BALANCE
---------- ------------ -----------
150 100 50
150 100 0
150 80 20
150 80 0
150 5 75
SQL>
Oracle 11g R2 架构设置:
CREATE TABLE lots ( Lot_Size, Reported_QTY ) AS
SELECT 150, 100 FROM DUAL
UNION ALL SELECT 150, 100 FROM DUAL
UNION ALL SELECT 150, 80 FROM DUAL
UNION ALL SELECT 150, 80 FROM DUAL
UNION ALL SELECT 150, 5 FROM DUAL;
查询 1:
SELECT Lot_Size,
Reported_QTY,
COALESCE( LAG( Reported_QTY ) OVER ( ORDER BY NULL ) - Reported_QTY,
Lot_Size - Reported_QTY ) AS Qty_Balance
FROM Lots
| LOT_SIZE | REPORTED_QTY | QTY_BALANCE |
|----------|--------------|-------------|
| 150 | 100 | 50 |
| 150 | 100 | 0 |
| 150 | 80 | 20 |
| 150 | 80 | 0 |
| 150 | 5 | 75 |