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中常用日期函数的具体使用
Apr 08 SQL Server
sqlserver2017共享功能目录路径不可改的解决方法
Apr 16 SQL Server
sql中mod()函数取余数的用法
May 29 SQL Server
解决sql server 数据库,sa用户被锁定的问题
Jun 11 SQL Server
SQLServer中JSON文档型数据的查询问题解决
Jun 27 SQL Server
SQL中的三种去重方法小结
Nov 01 SQL Server
SQL Server2019数据库备份与还原脚本,数据库可批量备份
Nov 20 SQL Server
MySQL 中如何归档数据的实现方法
Mar 16 SQL Server
SQLServer RANK() 排名函数的使用
Mar 23 SQL Server
sqlserver连接错误之SQL评估期已过的问题解决
Mar 23 SQL Server
SQL Server 忘记密码以及重新添加新账号
Apr 26 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
德生PL660的电路分析和打磨
2021/03/02 无线电
ThinkPHP框架任意代码执行漏洞的利用及其修复方法
2014/07/04 PHP
django中的ajax组件教程详解
2018/10/18 PHP
javascript qq右下角滑出窗口 sheyMsg
2010/03/21 Javascript
JavaScript call apply使用 JavaScript对象的方法绑定到DOM事件后this指向问题
2011/09/28 Javascript
jquery实现marquee效果(文字或者图片的水平垂直滚动)
2013/01/07 Javascript
浅析vue数据绑定
2017/01/17 Javascript
JavaScript编写的网页小游戏,很给力
2017/08/18 Javascript
Vue实现typeahead组件功能(非常靠谱)
2017/08/26 Javascript
Chart.js 轻量级HTML5图表绘制工具库(知识整理)
2018/05/22 Javascript
ES6与CommonJS中的模块处理的区别
2018/06/13 Javascript
JavaScript实现数组全排列、去重及求最大值算法示例
2018/07/30 Javascript
在Vue项目中用fullcalendar制作日程表的示例代码
2019/08/04 Javascript
详解vue+axios给开发环境和生产环境配置不同的接口地址
2019/08/16 Javascript
基于JS实现简单滑块拼图游戏
2019/10/12 Javascript
[02:17]快乐加倍!DOTA2食人魔魔法师至宝+迎霜节活动上线
2019/12/22 DOTA
[51:53]完美世界DOTA2联赛循环赛 LBZS vs DM BO2第二场 11.01
2020/11/02 DOTA
python 统计列表中不同元素的数量方法
2018/06/29 Python
python实现将多个文件分配到多个文件夹的方法
2019/01/07 Python
Python中使用__new__实现单例模式并解析
2019/06/25 Python
django 做 migrate 时 表已存在的处理方法
2019/08/31 Python
使用Python的datetime库处理时间(RPA流程)
2019/11/24 Python
Python字典深浅拷贝与循环方式方法详解
2020/02/09 Python
PyQt5 如何让界面和逻辑分离的方法
2020/03/24 Python
python实现扫雷小游戏
2020/04/24 Python
django Layui界面点击弹出对话框并请求逻辑生成分页的动态表格实例
2020/05/12 Python
利用python实现后端写网页(flask框架)
2021/02/28 Python
IE下实现类似CSS3 text-shadow文字阴影的几种方法
2011/05/11 HTML / CSS
css3弹性盒模型实例介绍
2013/05/27 HTML / CSS
英国香水店:The Perfume Shop
2017/03/27 全球购物
什么是动态端口(Dynamic Ports)?动态端口的范围是多少?
2014/12/12 面试题
银行职业规划书范文
2013/12/28 职场文书
结婚典礼证婚词
2014/01/08 职场文书
2014年煤矿工作总结
2014/11/24 职场文书
劳动仲裁撤诉申请书
2015/05/18 职场文书
PyQt5爬取12306车票信息程序的实现
2021/05/14 Python