3

我对 SQL 还是很陌生,对此我有点难过。我将不胜感激任何帮助或建议。我有一个表,其中包含一个值列和一个 ID 列,然后我按值列按降序排序。IE:

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. 计算 (1) 中为每个 ID 计算的百分比的累计。本质上只是每个 ID 的累积总和。

输出看起来像这样。

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  
4

5 回答 5

1

尝试使用 over() partition by () 语句

于 2013-08-08T03:28:33.707 回答
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 小提琴演示

于 2013-08-08T04:36:54.623 回答
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上试试

于 2013-08-08T04:55:35.870 回答
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
于 2013-08-08T03:42:03.603 回答
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 演示。

于 2013-08-08T04:06:43.790 回答