我在SQL Server 2014中有一组数据,我需要汇总到小计,并为每一行提供一个百分比。这是我需要做的简化示例:
示例数据:
SELECT * FROM myTable
Week Category Collection Sales
1 Red Good 4
1 Red Bad 5
1 Blue Good 2
1 Blue Bad 2
2 Red Good 3
2 Red Bad 1
2 Blue Good 4
2 Blue Bad 1
汇总部分很简单:
SELECT Week, Category, Collection, Sum(Sales) as Sales
FROM myTable
GROUP BY Week, Category, Collection WITH ROLLUP
Week Category Collection Sales
1 Red Good 4
1 Red Bad 5
1 Red NULL 9
1 Blue Good 2
1 Blue Bad 2
1 Blue NULL 4
1 NULL NULL 13
2 Red Good 3
2 Red Bad 1
2 Red NULL 4
2 Blue Good 4
2 Blue Bad 1
2 Blue NULL 5
2 NULL NULL 9
NULL NULL NULL 22
现在,我想要了解的是汇总的每个部分的累计百分比。像这样:
Week Category Collection Sales % Total
1 Red Good 4 .4444 (4/9)
1 Red Bad 5 .5556 (5/9)
1 Red NULL 9 .6923 (9/13)
1 Blue Good 2 .5 (2/4)
1 Blue Bad 2 .5 (2/4)
1 Blue NULL 4 .3077 (4/13)
1 NULL NULL 13 .5909 (13/22)
2 Red Good 3 .75 (3/4)
2 Red Bad 1 .25 (1/4)
2 Red NULL 4 .4444 (4/9)
2 Blue Good 4 .8 (4/5)
2 Blue Bad 1 .2 (1/5)
2 Blue NULL 5 .5556 (5/9)
2 NULL NULL 9 .4091 (9/22)
NULL NULL NULL 22
*注意,我不需要显示括号中显示的分数。这只是为了更容易看到计算。
我不确定如何处理SQL以获得这种结果。如果有人能让我指出正确的方向,我将非常感激。谢谢!
答案 0 :(得分:1)
您可以使用subquery
汇总:
SELECT Week, Category, Collection, Sum(Sales) as Sales,
1.0 * Sum(Sales) / (select sum(sales) from myTable where Week = m.Week and Category = m.Category) as [% Total]
FROM myTable m
GROUP BY Week, Category, Collection WITH ROLLUP;
但是,请注意除以零错误,您需要添加某些类型的预防,例如case
表达式或类似的东西。
答案 1 :(得分:1)
这是一种使用公用表表达式(CTE)使用分析函数预先计算可能分母然后执行聚合汇总的方法。在聚合查询中,通过使用分母中的合并运算符以及汇总中的分组集来确定百分比,使得在汇总的每个阶段,合并函数获得下一个连续分母值。您可以查看下面的查询和结果,或查看SQL Fiddle以查看设置和查询的实际效果。
with t1 as (
select week
, category
, collection
, sales
, sum(sales) over (partition by week, category) cat
, sum(sales) over (partition by week) w
, sum(sales) over () o
from mytable
)
select week
, category
, collection
, sum(sales) sales
, sum(sales)/coalesce(cat, w, o, sum(sales)) [% sales]
from t1
group by rollup(
(week, o)
, (category, w)
, (collection , cat))
order by 1, 2, 3
<强> Results 强>:
| week | category | collection | sales | % sales |
|--------|----------|------------|-------|----------|
| (null) | (null) | (null) | 22 | 1 |
| 1 | (null) | (null) | 13 | 0.590909 |
| 1 | Blue | (null) | 4 | 0.307692 |
| 1 | Blue | Bad | 2 | 0.5 |
| 1 | Blue | Good | 2 | 0.5 |
| 1 | Red | (null) | 9 | 0.692307 |
| 1 | Red | Bad | 5 | 0.555555 |
| 1 | Red | Good | 4 | 0.444444 |
| 2 | (null) | (null) | 9 | 0.40909 |
| 2 | Blue | (null) | 5 | 0.555555 |
| 2 | Blue | Bad | 1 | 0.2 |
| 2 | Blue | Good | 4 | 0.8 |
| 2 | Red | (null) | 4 | 0.444444 |
| 2 | Red | Bad | 1 | 0.25 |
| 2 | Red | Good | 3 | 0.75 |
采取Yogesh的解决方案并解决其下面的缺陷与上面的解决方案相同的结果。请参阅此SQL Fiddle以查看其实际效果:
SELECT Week
, Category
, Collection
, Sum(Sales) as Sales
, Sum(Sales)
/ (select sum(sales)
from myTable s
where (m.category is null or Week = m.Week)
and (m.collection is null or Category = m.Category)
) as [% Total]
FROM myTable m
GROUP BY Week, Category, Collection WITH ROLLUP
order by 1, 2, 3;