sql server 累计求和实现代码


Posted in SQL Server onFebruary 28, 2022

看了一眼自关联,没搞懂,试了一下也没成功。

over方式一下结果就出来了,好用。

/*
需求:累计求和六种算法效率比较
作者:felix
日期:2020-06-23

*/
--第一步,准备测试数据
--IF OBJECT_ID(N'dbo.t') IS NOT NULL
--	DROP TABLE dbo.t;
--GO
--CREATE TABLE dbo.t
--(
--	i BIGINT IDENTITY(1, 1) PRIMARY KEY,
--	d MONEY
--);
--INSERT t
--	d
--)
--SELECT TOP 31465
--	   ROUND(10000 * RAND(CHECKSUM(NEWID())), 2)
--FROM sys.all_objects AS a
--	CROSS JOIN sys.all_objects;
----第二步,创建记录时间的表格
--IF OBJECT_ID(N'dbo.record_time') IS NOT NULL
--	DROP TABLE dbo.record_time;
--CREATE TABLE dbo.record_time
--	i INT IDENTITY PRIMARY KEY,
--	算法 NVARCHAR(10),
--	bt DATETIME2,--开始时间
--	et DATETIME2,--结束时间
--	idiff AS DATEDIFF(ms, bt, et)--所用的毫秒数
--第一种方法,自连接法,sql server 2008以上版本测试通过,157255661.40
SET STATISTICS TIME OFF;
SET STATISTICS IO OFF;
GO
DECLARE @bt DATETIME2 = GETDATE();
SELECT a.i,
       a.d,
       SUM(b.d) AS total_sum
FROM dbo.t AS a
    INNER JOIN dbo.t AS b
        ON b.i <= a.i
GROUP BY a.i,
         a.d;
DECLARE @et DATETIME2 = GETDATE();
INSERT INTO dbo.record_time
(
    算法,
    bt,
    et
)
VALUES
('自连接', @bt, @et);
--ORDER BY a.i;
;
--第二种方法,递归,sql server 2008以上版本测试通过,157255661.40
WITH cte_total_sum
AS (SELECT i,
           d,
           d AS total_sum
    FROM dbo.t
    WHERE i = 1
    UNION ALL
    SELECT s.i,
           s.d,
           p.total_sum + s.d AS total_sum
    FROM dbo.t AS s
        INNER JOIN cte_total_sum AS p
            ON s.i - 1 = p.i)
SELECT *
FROM cte_total_sum
OPTION (MAXRECURSION 0);
('递归', @bt, @et);
--第三种方法,over 子句,sql server 2012测试通过,sql server 2008不支持,157255661.40
SELECT i,
       d,
       SUM(d) OVER (ORDER BY i) AS total_sum
FROM dbo.t;
('over子句', @bt, @et);
--第四种,相关子查询,sql server 2008以上版本测试通过,156625045.22
SELECT outquery.i,
       outquery.d,
       (
           SELECT SUM(innerq.d) FROM dbo.t AS innerq WHERE innerq.i <= outquery.i
       ) AS ct --内部查询
FROM dbo.t AS outquery;
('相关子查询', @bt, @et);
--ORDER BY outquery.i; --外部查询
--游标方法,有两种方法可以实现,一种是临时表更新,一种是变量叠加更新,157255661.40
--先增加一个存储累计和的列
--第5种,游标_临时表更新
--ALTER TABLE dbo.t ADD total_d MONEY DEFAULT (0);--只运行一次
DECLARE @t TABLE --定义表变量,存储累计求和临时结果
    i INT PRIMARY KEY IDENTITY,
    d MONEY,
    total_d MONEY
);
DECLARE @i INT = 0,
        @d MONEY = 0,
        @total_d MONEY = 0;
DECLARE c1 CURSOR FOR SELECT i, d FROM dbo.t ORDER BY i;
OPEN c1;
FETCH c1
INTO @i,
     @d;
WHILE @@FETCH_STATUS = 0
BEGIN
    SET @total_d += @d;
    INSERT INTO @t
    (
        d,
        total_d
    )
    VALUES
    (@d, @total_d);
    FETCH c1
    INTO @i,
         @d;
END;
CLOSE c1;
DEALLOCATE c1;
UPDATE dbo.t
SET total_d = b.total_d
    INNER JOIN @t AS b
        ON a.i = b.i;
('游标_临时表更新', @bt, @et);
--第6种,游标_变量叠加更新
DECLARE c1 CURSOR FOR SELECT i, d FROM dbo.t; --ORDER BY i;
    UPDATE dbo.t
    SET total_d = @total_d
    WHERE i = @i;
('游标_变量叠加更新', @bt, @et);
--执行时间 over子句<游标临时表更新<游标变量叠加更新<自连接<相关子查询<递归查询

补充:下面看下SQL server 累加求和

SQL server 累加求和

1.

SELECT SalesOrderID, ProductID, OrderQty
    ,SUM(OrderQty) OVER(PARTITION BY SalesOrderID) AS Total
    ,AVG(OrderQty) OVER(PARTITION BY SalesOrderID) AS "Avg"
    ,COUNT(OrderQty) OVER(PARTITION BY SalesOrderID) AS "Count"
    ,MIN(OrderQty) OVER(PARTITION BY SalesOrderID) AS "Min"
    ,MAX(OrderQty) OVER(PARTITION BY SalesOrderID) AS "Max"
FROM Sales.SalesOrderDetail 
WHERE SalesOrderID IN(43659,43664);

2.

select SchSno,convert(varchar(10),a.Dates,120) Dates,
sum(Amt_avail) over(partition by SchSno order by convert(varchar(10),a.Dates,120)) as PeriodPreAmt
from jr_creditUserAcct a

到此这篇关于sql server 累计求和实现代码的文章就介绍到这了,更多相关sql server 累计求和内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

SQL Server 相关文章推荐
SQL Server2019数据库之简单子查询的具有方法
Apr 27 SQL Server
如何有效防止sql注入的方法
May 25 SQL Server
解决sql server 数据库,sa用户被锁定的问题
Jun 11 SQL Server
sql字段解析器的实现示例
Jun 23 SQL Server
SQLServer中JSON文档型数据的查询问题解决
Jun 27 SQL Server
sql通过日期判断年龄函数的示例代码
Jul 16 SQL Server
详解在SQLPlus中实现上下键翻查历史命令的功能
Mar 18 SQL Server
SQL Server使用导出向导功能
Apr 08 SQL Server
SQL Server数据库查询出现阻塞之性能调优
Apr 10 SQL Server
SQL Server使用T-SQL语句批处理
May 20 SQL Server
SQL bool盲注和时间盲注详解
Jul 23 SQL Server
详解SQL报错盲注
Jul 23 SQL Server
SQL SERVER触发器详解
Feb 24 #SQL Server
SQL SERVER存储过程用法详解
Feb 24 #SQL Server
SQL SERVER实现连接与合并查询
Feb 24 #SQL Server
SQLServer中exists和except用法介绍
SQL Server2019数据库备份与还原脚本,数据库可批量备份
SQL中的三种去重方法小结
Nov 01 #SQL Server
SQL Server表分区删除详情
You might like
简单的移动设备检测PHP脚本代码
2011/02/19 PHP
php简单浏览目录内容的实现代码
2013/06/07 PHP
php发送与接收流文件的方法
2015/02/11 PHP
PHP简单实现解析xml为数组的方法
2018/05/02 PHP
jquery tools 系列 scrollable(2)
2009/09/06 Javascript
innerhtml用法 innertext用法 以及innerHTML与innertext的区别
2009/10/26 Javascript
javascript中的startWith和endWith的几种实现方法
2013/05/07 Javascript
javascript实现画不相交的圆
2015/04/07 Javascript
js实现表单检测及表单提示的方法
2015/08/14 Javascript
JS处理json日期格式化问题
2015/10/01 Javascript
AngularJS入门教程中SQL实例详解
2016/07/27 Javascript
使用DataTable插件实现异步加载数据
2017/11/19 Javascript
AngularJs 禁止模板缓存的方法
2017/11/28 Javascript
微信小程序支付PHP代码
2018/08/23 Javascript
JavaScript继承与聚合实例详解
2019/01/22 Javascript
微信小程序云开发详细教程
2019/05/16 Javascript
Javascript Dom元素获取和添加详解
2019/09/24 Javascript
JQuery通过键盘控制键盘按下与松开触发事件
2020/08/07 jQuery
原生JavaScript实现轮播图
2021/01/10 Javascript
[51:29]完美世界DOTA2联赛循环赛 Matador vs Forest BO2第一场 11.05
2020/11/05 DOTA
基于Python实现通过微信搜索功能查看谁把你删除了
2016/01/27 Python
Django 静态文件配置过程详解
2019/07/23 Python
python matplotlib库直方图绘制详解
2019/08/10 Python
手摸手教你用canvas实现给图片添加平铺水印的实现
2019/08/20 HTML / CSS
如何给HTML标签中的文本设置修饰线
2019/11/18 HTML / CSS
美国打印机墨水和碳粉购物网站:QuikShip Toner
2018/08/29 全球购物
香港最大的洋酒零售连锁店:屈臣氏酒窖(Watson’s Wine)
2018/12/10 全球购物
三个Unix的命令面试题
2015/04/12 面试题
毕业生求职信
2014/06/10 职场文书
委托函范文
2015/01/29 职场文书
大学生自我评价范文
2015/03/03 职场文书
试用期旷工辞退通知书
2015/04/17 职场文书
音乐剧猫观后感
2015/06/04 职场文书
股权投资协议书
2016/03/23 职场文书
关于flex 上下文中自动 margin的问题(完整例子)
2021/05/20 HTML / CSS
深入解读Java三大集合之map list set的用法
2021/11/11 Java/Android