原文:https://zhuanlan.zhihu.com/p/150291837
看了一眼自關聯,沒搞懂,試了一下也沒成功。
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; --GO --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; GO ; --第二種方法,遞歸,sql server 2008以上版本測試通過,157255661.40 DECLARE @bt DATETIME2 = GETDATE(); 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); DECLARE @et DATETIME2 = GETDATE(); INSERT INTO dbo.record_time ( 算法, bt, et ) VALUES ('遞歸', @bt, @et); GO