【问题标题】:SUM a specific column in next rows until a condition is true对下一行中的特定列求和,直到条件为真
【发布时间】:2021-12-29 09:44:40
【问题描述】:

这是一个文章表,我想根据条件将 next rowsMass Column 的总和存储在 sumNext Column 中。

如果下一行与当前行具有相同的楼层(在 floorNo 列中),则添加下一行的质量,直到楼层发生变化

例如:第三行有 sumNext = 2。这是通过将第 4 行和第 5 行的质量相加来计算的,因为这两行的楼层数与第 3 行相同。

id mass symbol floorNo sumNext
2891176 1 D 1 0
2891177 1 L 8 0
2891178 1 L 1 2
2891179 1 L 1 1
2891180 1 1 0
2891181 1 5 2
2891182 1 5 1
2891183 1 5 0

这里是查询,就是生成这个表,我只想在里面加上正确值的 sumNext 列。

WITH items AS (SELECT 
SP.id,
    SP.mass,
    SP.symbol,
    SP.floorNo
FROM articles SP
        ORDER BY  
          DECODE(SP.symbol,
            'P',1,
            'D',2,
            'L',3,
              4 ) asc)
SELECT CLS.*
FROM items CLS;

【问题讨论】:

    标签: sql oracle plsql


    【解决方案1】:

    您可以使用以下使用的解决方案

    • 公用表表达式 (cte) 技术将具有相同 FLOORNO 值的所有连续行放在同一组中(新 grp 列)。
    • 然后根据需要使用 SUM 函数的分析版本对每个 grp 列的所有下一个 MASS 求和。
    Items_RowsNumbered (id, mass, symbol, floorNo, rnb) as (
      select ID, MASS, SYMBOL, FLOORNO
        , row_number()over( 
              order by DECODE(symbol, 'P',1, 'D',2, 'L',3, 4 ) asc, ID )
      /*
        You need to add ID column (or any others columns that can identify each row uniquely)
        in the "order by" clause to make the result deterministic
        */
      from (Your source query)Items
    )
    , cte(id, mass, symbol, floorNo, rnb, grp) as (
      select id, mass, symbol, floorNo, rnb, 1 grp
      from Items_RowsNumbered
      where rnb = 1
      union all
      select t.id, t.mass, t.symbol, t.floorNo, t.rnb
        , case when t.floorNo = c.floorNo then c.grp else c.grp + 1 end grp
      from Items_RowsNumbered t
      join cte c on (c.rnb + 1 = t.rnb)
    )
    select 
        ID, MASS, SYMBOL, FLOORNO
      /*, RNB, GRP*/
      , nvl(
            sum(MASS)over(
              partition by grp
                order by rnb 
                  ROWS BETWEEN 1 FOLLOWING and UNBOUNDED FOLLOWING)
           , 0 
          ) sumNext
    from cte
    ;
    

    demo on db<>fiddle

    【讨论】:

    • 这个对我有用,谢谢
    • 很高兴看到我能提供帮助。
    【解决方案2】:

    这是一个典型的gaps-and-islands 问题。您可以使用LAG() 来确定确切的分区,然后使用SUM() 解析函数如

    WITH ii AS
    (
     SELECT i.*,
            ROW_NUMBER() OVER (ORDER BY id DESC) AS rn2,
            ROW_NUMBER() OVER (PARTITION BY floorNo ORDER BY id DESC) AS rn1
       FROM items i
    )
    SELECT id,mass,symbol, floorNo, 
           SUM(mass) OVER (PARTITION BY rn2-rn1 ORDER BY id DESC)-1 AS sumNext
      FROM ii 
     ORDER BY id
    

    Demo

    【讨论】:

    • 但顺序不应该涉及ID列,应该根据符号列中的自定义字母 DECODE(SP.symbol, 'P',1, 'D',2, 'L', 3, 4)
    猜你喜欢
    • 1970-01-01
    • 2016-09-12
    • 2022-06-25
    • 2018-02-19
    • 2015-06-12
    • 1970-01-01
    • 2021-04-27
    • 2020-11-13
    • 1970-01-01
    相关资源
    最近更新 更多