【问题标题】:SQL Server: cumulative percentage with "group by" on many fieldsSQL Server:在许多字段上使用“分组依据”的累积百分比
【发布时间】:2011-09-07 09:43:00
【问题描述】:

我有这张表,我想计算每个 TYPE_MATERIAL/YEARS 的累积百分比

declare @mytable table (TYPE_MATERIAL int, YEARS int, ROW_NUM int, PERCENTUAL_PRICE numeric(6,2))
insert @mytable
select 1,2010,1,54.5
union all select 1,2010,2,37.5
union all select 1,2010,3,8.0

union all select 1,2009,1,72.8
union all select 1,2009,2,21.0
union all select 1,2009,3,6.2

union all select 2,2010,1,61.0
union all select 2,2010,2,36.0
union all select 2,2010,3,3.0

结果应该是这样的:

TYPE_MATERIAL YEARS       ROW_NUM     PERCENTUAL_PRICE    PERCENTUAL_PRICE_cumulative
1             2010        1           54.50               54.5 (=54.5)
1             2010        2           37.50               92.0 (=54.5+37.5)
1             2010        3           8.00                100.0 (=54.5+37.5+8)
1             2009        1           72.80               72.8
1             2009        2           21.00               93.8
1             2009        3           6.20                100.0
2             2010        1           61.00               61.0
2             2010        2           36.00               97.0
2             2010        3           3.00                100.0

我在互联网上找到了这个查询,但它不适用于这种情况,因为它仅在我有一个 TYPE_MATERIAL 和一个 YEARS 时才计算累积百分比

select TYPE_MATERIAL, YEARS, ROW_NUM, PERCENTUAL_PRICE,
PERCENTUAL_PRICE_cumulative=
(
select SUM(PERCENTUAL_PRICE) from @mytable b
where b.ROW_NUM<=a.ROW_NUM
)
from @mytable a

有什么建议吗? 谢谢

【问题讨论】:

    标签: sql sql-server cumulative-sum


    【解决方案1】:
    select TYPE_MATERIAL, YEARS, ROW_NUM, PERCENTUAL_PRICE,
    PERCENTUAL_PRICE_cumulative=
    (
    select SUM(PERCENTUAL_PRICE) from @mytable b
    where b.ROW_NUM<=a.ROW_NUM AND b.YEARS = a.YEARS AND b.TYPE_MATERIAL = a.TYPE_MATERIAL
    )
    from @mytable a
    

    【讨论】:

      【解决方案2】:

      您的问题是由于您的内部查询不限制 type_material 和 years。

      select TYPE_MATERIAL, YEARS, ROW_NUM, PERCENTUAL_PRICE,
      PERCENTUAL_PRICE_cumulative=
      (
      select SUM(PERCENTUAL_PRICE) from @mytable b
      where b.ROW_NUM<=a.ROW_NUM AND b.type_material = a.type_material AND b.years = a.years
      )
      from @mytable a
      

      您也可以使用递归 CTE 来执行此操作,它对于非常大的数据应该可以执行。

      with myCte (TYPE_MATERIAL, YEARS, ROW_NUM, PERCENTUAL_PRICE, PERCENTUAL_PRICE_cumulative)
      as
      (
          select TYPE_MATERIAL, YEARS, ROW_NUM, PERCENTUAL_PRICE, PERCENTUAL_PRICE AS PERCENTUAL_PRICE_cumulative
          FROM @mytable
          WHERE row_num = 1
          UNION ALL
          select t.TYPE_MATERIAL, t.YEARS, t.ROW_NUM, t.PERCENTUAL_PRICE, CAST(t.PERCENTUAL_PRICE + myCte.PERCENTUAL_PRICE_cumulative AS  numeric(6,2)) AS PERCENTUAL_PRICE_cumulative
          FROM @mytable t
              INNER JOIN myCte ON myCte.type_material = t.type_material AND myCte.years = t.years AND mycte.row_num = t.row_num-1
          WHERE t.row_num > 1
      )
      SELECT * FROM myCte
      ORDER BY  TYPE_MATERIAL, YEARS, ROW_NUM
      

      【讨论】:

        【解决方案3】:

        这应该用窗口函数解决,而不是递归或子查询:

        SELECT
          type_material, years, row_num, percentual_price
          SUM (percentual_price) OVER (PARTITION BY type_material, years ORDER BY row_num) cumulative
        FROM @mytable
        

        【讨论】:

          猜你喜欢
          • 2013-06-10
          • 2018-09-08
          • 2012-02-24
          • 2021-09-23
          • 1970-01-01
          • 1970-01-01
          • 2021-03-08
          • 2017-03-03
          • 2020-08-03
          相关资源
          最近更新 更多