我如何从第二列运行总计

Posted

技术标签:

【中文标题】我如何从第二列运行总计【英文标题】:How do i do running totals from second column 【发布时间】:2015-05-21 13:15:59 【问题描述】:

我有一个如下的数据集,

Lot Size    Reported QTY    Qty Balance
150          100            
150          100            
150          80             
150          80            
150          5              

数量余额需要计算如下,

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

如何在查询中实现这一点?

【问题讨论】:

所有很好的答案.. 谢谢大家!我只是选择了最适合我的答案作为最佳答案.. 【参考方案1】:

SQL Fiddle

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

Results

| LOT_SIZE | REPORTED_QTY | QTY_BALANCE |
|----------|--------------|-------------|
|      150 |          100 |          50 |
|      150 |          100 |           0 |
|      150 |           80 |          20 |
|      150 |           80 |           0 |
|      150 |            5 |          75 |

【讨论】:

您不需要合并 - 您可以完全在 lag 函数中完成。我用一个例子更新了我的答案。【参考方案2】:

您应该看看LAG() 分析函数。有关函数及其接受的参数的详细信息,请参阅here(例如,我认为您需要在 lag() 函数返回 null 时传入 lot_size 列的默认值。)

一旦您确定了上一行报告的数量值,您就可以简单地减去它。当然,您将需要某种方法来识别行的顺序——您的示例数据似乎没有,因此数据库将无法确定哪一行是第一行,哪一行是最后一行。

例如。

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

【讨论】:

【参考方案3】:

正如@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>

【讨论】:

您不需要 case 语句 - 您可以完全在 lag 函数中完成。我用一个例子更新了我的答案。 @Boneist 是的,微妙! offsetdefault 是键。好点子,谢谢。 @Boneist 抱歉拼错了你的名字...顺便说一句,我们可以在有一天见面时一起创作一些好音乐。将向您展示我的吉他和歌唱技巧:-) 没关系;我见过各种各样的变化 *;-) 不过,我不太确定吉他和长号能不能很好地混合!

以上是关于我如何从第二列运行总计的主要内容,如果未能解决你的问题,请参考以下文章

从第二列开始填充数据表

从第二列的开头删除空格

在 Spark 数据集中创建具有运行总计的列

组合2个字符串的最快方法,将字符串从第二列交错到整个数据帧中的第一列

QT:如何检查 qt 表格小部件中是不是有空单元格

GridLayoutManager均分网格