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 Server基本使用和简单的CRUD操作
Apr 05 SQL Server
SqlServer: 如何更改表的文件组?(进而改变存储位置)
Apr 05 SQL Server
SQL Server中交叉联接的用法详解
Apr 22 SQL Server
如何有效防止sql注入的方法
May 25 SQL Server
SQL Server中使用判断语句(IF ELSE/CASE WHEN )案例
Jul 07 SQL Server
SQL SERVER触发器详解
Feb 24 SQL Server
sql时间段切分实现每隔x分钟出一份高速门架车流量
Feb 28 SQL Server
sqlserver连接错误之SQL评估期已过的问题解决
Mar 23 SQL Server
SQL Server使用导出向导功能
Apr 08 SQL Server
SQL Server Agent 服务无法启动
Apr 20 SQL Server
SQL Server中T-SQL标识符介绍与无排序生成序号的方法
May 25 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/10/13 PHP
PHP中如何判断AJAX提交的数据
2012/02/05 PHP
php实现mysql数据库分表分段备份
2015/06/18 PHP
今天你说520了吗?不仅有php表白书还有java表白神器
2016/05/20 PHP
thinkphp5 加载静态资源路径与常量的方法
2017/12/24 PHP
自写的利用PDO对mysql数据库增删改查操作类
2018/02/19 PHP
Code:findPosX 和 findPosY
2006/12/20 Javascript
jquery toolbar与网页浮动工具条具体实现代码
2014/01/12 Javascript
javascript/jquery获取地址栏url参数的方法
2014/03/05 Javascript
JavaScript中的console.dir()函数介绍
2014/12/29 Javascript
JavaScript的内存释放问题详解
2015/01/21 Javascript
javascript实现客户端兼容各浏览器创建csv并下载的方法
2015/03/23 Javascript
AngularJS $injector 依赖注入详解
2016/09/14 Javascript
原生JS封装animate运动框架的实例
2017/10/12 Javascript
微信小程序 input输入及动态设置按钮的实现
2017/10/27 Javascript
Python简单的制作图片验证码实例
2017/05/31 Python
详解tensorflow实现迁移学习实例
2018/02/10 Python
Python爬虫PyQuery库基本用法入门教程
2018/08/04 Python
Python帮你识破双11的套路
2019/11/11 Python
使用Python实现正态分布、正态分布采样
2019/11/20 Python
Python partial函数原理及用法解析
2019/12/11 Python
python实现局域网内实时通信代码
2019/12/22 Python
python脚本实现mp4中的音频提取并保存在原目录
2020/02/27 Python
浅谈python出错时traceback的解读
2020/07/15 Python
delegate与普通函数的区别
2014/01/22 面试题
应届生煤化工求职信
2013/10/21 职场文书
关于学习的演讲稿
2014/05/10 职场文书
八一建军节营销活动方案
2014/08/31 职场文书
公司试用期员工自我评价
2014/09/17 职场文书
捐助感谢信
2015/01/22 职场文书
给上级领导的感谢信
2015/01/22 职场文书
报名委托书
2015/01/29 职场文书
2016年小学六一儿童节活动总结
2016/04/06 职场文书
python本地文件服务器实例教程
2021/05/02 Python
详细聊聊vue中组件的props属性
2021/11/02 Vue.js
简单聊聊TypeScript只读修饰符
2022/04/06 Javascript