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 相关文章推荐
SQLServer2008提示评估期已过解决方案
Apr 12 SQL Server
SQL Server中交叉联接的用法详解
Apr 22 SQL Server
数据库之SQL技巧整理案例
Jul 07 SQL Server
sql通过日期判断年龄函数的示例代码
Jul 16 SQL Server
sql server删除前1000行数据的方法实例
Aug 30 SQL Server
SQL SERVER触发器详解
Feb 24 SQL Server
Sql Server之数据类型详解
Feb 28 SQL Server
sql时间段切分实现每隔x分钟出一份高速门架车流量
Feb 28 SQL Server
SQL Server 忘记密码以及重新添加新账号
Apr 26 SQL Server
SQL Server 中的事务介绍
May 20 SQL Server
一次SQL查询优化原理分析(900W+数据从17s到300ms)
Jun 10 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简单创建zip压缩文件的方法
2016/04/30 PHP
thinkPHP实现的联动菜单功能详解
2017/05/05 PHP
基于PHP+Mysql简单实现了图书购物车系统的实例详解
2020/08/06 PHP
JavaScript与函数式编程解释
2007/04/27 Javascript
Jquery 插件开发笔记整理
2011/01/17 Javascript
jQuery下通过$.browser来判断浏览器.
2011/04/05 Javascript
javascript实现按回车键切换焦点
2015/02/09 Javascript
JavaScript判断字符长度、数字、Email、电话等常用判断函数分享
2015/04/01 Javascript
详解JavaScript中的Unescape()和String() 函数
2015/11/09 Javascript
js格式化时间的方法
2015/12/18 Javascript
JS Array.slice 截取数组的实现方法
2016/01/02 Javascript
JavaScript焦点事件、鼠标事件和滚轮事件使用详解
2016/01/15 Javascript
JavaScript文本框脚本编写的注意事项
2016/01/25 Javascript
基于HTML+CSS+JS实现增加删除修改tab导航特效代码
2016/08/05 Javascript
javascript cookie用法基础教程(概念,设置,读取及删除)
2016/09/20 Javascript
EasyUI学习之DataGird分页显示数据
2016/12/29 Javascript
ajax的分页查询示例(不刷新页面)
2017/01/11 Javascript
EasyUi 打开对话框后控件赋值及赋值后不显示的问题解决办法
2017/01/19 Javascript
ES6新特性五:Set与Map的数据结构实例分析
2017/04/21 Javascript
vue实现a标签点击高亮方法
2018/03/17 Javascript
JavaScript Reflect Metadata实现详解
2019/12/12 Javascript
[05:59]2018DOTA2国际邀请赛寻真——只为胜利的Secret
2018/08/13 DOTA
python读取浮点数和读取文本文件示例
2014/05/06 Python
python使用xlrd实现检索excel中某列含有指定字符串记录的方法
2015/05/09 Python
Python os.access()用法实例
2019/02/18 Python
Python如何进行时间处理
2020/08/06 Python
html5实现多文件的上传示例代码
2014/02/13 HTML / CSS
德国婴儿服装和婴儿用品购买网站:Baby Sweets
2019/12/08 全球购物
表彰先进集体通报
2014/01/12 职场文书
中学生获奖感言
2014/02/04 职场文书
环保建议书300字
2014/05/14 职场文书
启动仪式策划方案
2014/06/14 职场文书
教师优秀党员事迹材料
2014/08/14 职场文书
2015公务员试用期工作总结
2014/12/12 职场文书
2015年七一建党节活动总结
2015/03/20 职场文书
只用50行Python代码爬取网络美女高清图片
2021/06/02 Python