我还是SQL的新手,对此很难受。我非常感谢任何帮助或建议。我有一个带有值列和ID列的表,然后我按值列按降序排序。即:
Value | ID
12 | A
09 | A
08 | B
08 | C
07 | A
06 | B
03 | B
01 | C
我正在尝试做两件事:
输出看起来像这样。
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
答案 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]
答案 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。