我正在阅读这里的教程:http ://www.1keydata.com/sql/sql-running-totals.html这一切都是有道理的,直到它突然变得非常荒谬,令人难以置信的复杂,当它得到排名时,中位数,运行总数等。有人可以用简单的英语解释该查询如何产生运行总数吗?谢谢!
4 回答
在我开始之前,我以前从未见过这种情况,而且它看起来不是一种非常容易理解的方式来完成运行总计。
好的,这是教程中的查询:
SELECT a1.Name, a1.Sales, SUM(a2.Sales) Running_Total
FROM Total_Sales a1, Total_Sales a2
WHERE a1.Sales <= a2.sales or (a1.Sales=a2.Sales and a1.Name = a2.Name)
GROUP BY a1.Name, a1.Sales
ORDER BY a1.Sales DESC, a1.Name DESC;
和样本输出
Name Sales Running_Total
Greg 50 50
Sophia 40 90
Stella 20 110
Jeff 20 130
Jennifer 15 145
John 10 155
此查询的简单部分是显示每个员工的销售数据。我们所做的只是从每个员工中挑选name
并按sales
销售额(降序)对他们进行排序。这给了我们我们的基本清单。
现在对于运行总计,我们想要已经显示的每一行。因此,我们将表格与自身连接起来,在已经显示的每一行上:
WHERE a1.Sales <= a2.sales or (a1.Sales=a2.Sales and a1.Name = a2.Name)
然后我们使用SUM
聚合函数并相应地分组。理解这一点的一个好方法是看看如果不使用 group 函数会发生什么。'Sophia' 行看起来像这样:
Name A1.Sales A2.Sales
Sophia 40 50
Sophia 40 40
注意我们是如何得到 Greg 的销售行的?该小组将总结这一点,瞧!
希望有帮助。乔
第一个表连接到自身,连接产生 x 行数,其中 x 是总销售额低于自身的行数,或者行中的名称相同(即我们行之前的所有销售额)正在查看,按销售额订购时)。
然后,它对连接左侧的字段进行分组,并对我们连接到的行求和,从而得出运行总计。要查看它是如何工作的,您可能希望在没有总和和分组的情况下运行它,以查看返回的原始结果。
上面的 SQL 在 Sybase (ASE 15) 上给出了不同的结果。我认为原因是直到显示时间才应用“order by”。这是 SQL 和结果:
drop table Total_Sales
go
create table Total_Sales
(
Name char(15),
Sales int
)
INSERT INTO Total_Sales VALUES( 'John', 10 )
INSERT INTO Total_Sales VALUES( 'Jennifer', 15)
INSERT INTO Total_Sales VALUES('Stella', 20 )
INSERT INTO Total_Sales VALUES('Sophia', 40 )
INSERT INTO Total_Sales VALUES('Greg', 50 )
INSERT INTO Total_Sales VALUES('Jeff', 20 )
SELECT a1.Name, a1.Sales, SUM(a2.Sales) Running_Total
FROM Total_Sales a1, Total_Sales a2
WHERE a1.Sales <= a2.Sales or (a1.Sales=a2.Sales and a1.Name = a2.Name)
GROUP BY a1.Name, a1.Sales
ORDER BY a1.Sales DESC, a1.Name DESC
结果:
Name Sales Running_Total
Greg 50 50
Sophia 40 90
Stella 20 130 --note that two running totals are the same!
Jeff 20 130
Jennifer 15 145
John 10 155
鲍勃
我也得到了与上面 Bob 相同的错误输出,其中 Stella 和 Jeff 的运行总数分解,他们具有相同的销售数字。我正在使用 SQL Server 2014 Management Studio Express。我不认为该网站的解决方案实际上是正确的。我根据名称而不是销售额进行了加入,并提出了这些,从而产生了正确的运行总计:
select a1.name
, a1.sales
, sum(a2.sales) 'running_total'
from #total_sales a1
inner join #total_sales a2 on a1.name <= a2.name
group by a1.name, a1.sales
order by sum(a2.sales);
产量:
name sales running_total
Stella 20 20
Sophia 40 60
John 10 70
Jennifer 15 85
Jeff 20 105
Greg 50 155
如果您对聚合排序感到不舒服,您也可以执行以下变体。它改变了顺序,但运行总数仍然正确:
select a1.name
, a1.sales
, sum(a2.sales) 'running_total'
from #total_sales a1
inner join #total_sales a2 on a1.name >= a2.name
group by a1.name, a1.sales
order by a1.name;
产量:
name sales running_total
Greg 50 50
Jeff 20 70
Jennifer 15 85
John 10 95
Sophia 40 135
Stella 20 155