SQL单位值和按组的累积总和

时间:2013-08-08 03:24:27

标签: sql

我还是SQL的新手,对此很难受。我非常感谢任何帮助或建议。我有一个带有值列和ID列的表,然后我按值列按降序排序。即:

Value   | ID   
12      | A  
09      | A  
08      | B  
08      | C  
07      | A  
06      | B  
03      | B  
01      | C  

我正在尝试做两件事:

  1. 对于每一行,计算其各自ID的总和百分比。第1行为12 /(12 + 9 + 7),第2行:3 /(12 + 9 + 7),第3行:8 /(8 + 6 + 3)等。
  2. 计算每个ID在(1)中计算的百分比的运行总和。基本上只是每个ID的累积总和。
  3. 输出看起来像这样。

    Value | ID | UnitValue | RunningTotal  
    -------------------------------------
      12  | A  | 0.43      | 0.43  
      09  | A  | 0.32      | 0.75  
      08  | B  | 0.47      | 0.47  
      08  | C  | 0.89      | 0.89  
      07  | A  | 0.25      | 1.00  
      06  | B  | 0.35      | 0.82  
      03  | B  | 0.18      | 1.00  
      01  | C  | 0.11      | 1.00  
    

5 个答案:

答案 0 :(得分:1)

尝试使用 over()分区by() 声明

答案 1 :(得分:1)

对于SQL Server 2008

;WITH CTE 
AS
(
    SELECT
        Value
        ,ID
        ,CONVERT(DECIMAL(10,2),Value/CONVERT(DECIMAL(10,2),SUM(Value) OVER(PARTITION BY [ID]))) AS [Unit Value]
    FROM
        Table1 

)

SELECT a.Value,a.ID,a.[Unit Value], (SELECT SUM(b.[Unit Value])
               FROM   CTE b
               WHERE a.ID = b.ID AND b.[Unit Value] <= a.[Unit Value]) AS [RunningTotal]
FROM   CTE a
ORDER  BY a.ID,[RunningTotal]

SQL FIDDLE DEMO

答案 2 :(得分:1)

在SQL Server 2012或PostgreSQL中,您可以使用窗口函数,查询变得相当简单:

;with cte as (
  select
      Value, ID,
      cast(sum(Value) over(partition by ID) as decimal(29, 10)) as sum_id
  from Table1
)
select
    Value, ID,
    cast(Value / sum_id as decimal(29, 2)) as UnitValue, 
    cast(sum(Value / sum_id) over(partition by ID order by Value desc) as decimal(29, 2)) as RunningTotal
from cte

您可以使用示例

sql fiddle上进行尝试

答案 3 :(得分:0)

这是一个相当便携的查询,它将获得前3列。可以通过各种方式实现运行总计,包括Microsoft SQL Server上的CTE。

注意:CASE块用于防止除零错误。

SELECT
    T.Value,
    T.ID,
    CASE
        WHEN SUMS.Total = 0 THEN 0.00
        ELSE (T.Value / SUMS.Total)
    END AS UnitValue
FROM
    MyTable T
    INNER JOIN
    (
    SELECT
        T1.ID,
        SUM(COALESCE(T1.Value, 1)) AS Total
    FROM
        MyTable T1
    GROUP BY
        T1.ID
    ) AS SUMS ON
        SUMS.ID = T.ID

答案 4 :(得分:0)

如果您使用的是Oracle,则可以使用RATIO_TO_REPORT来计算比率,并使用SUM作为分析函数来计算累积总和。

select value,
       id,
       r,
       sum(r) over (partition by id order by value desc) s
  from(
  select value,
         id,
         round(ratio_to_report(value) over (partition by id),2) r
    from mytable)
order by value desc;

SUM在其他数据库中可用,但不确定RATIO_TO_REPORT

Oracle演示here