目前我在SQL Server 2008中有以下循环函数:
DECLARE @I int = 0
DECLARE @X int = 0
DECLARE @withdrawlCosntant float = 0.25
DECLARE @signups int = 0
WHILE @I<=12
BEGIN
WHILE @X <= 24
BEGIN
SET @X = @X + 1
SET @signups = (SELECT Singups FROM TraineeCredits WHERE I = @I AND X = @X)
INSERT TraineeForecast(I, X, Signups)
VALUES (@I, @X + 1, @signups - @singups * @withdrawlConstant)
END
SET @X = @I
SET @I = @I + 1
END
GO
虽然这有效,但对我来说速度极慢。
编辑: 我如何创建一种推送行的方法? 基本上我和X就像一个轴中的轴。
我们有行:
(I,X,Signups)
(0,1,2)
(0,2,4)
(0,3,1)
我如何将其推下来为下一个I = 1?
(I,X,Signups)
(1,1,0)
(1,2,2)
(1,3,4)
(1,4,1)
记住最大X为24.对于I = 2,它看起来像:
(I,X,Signups)
(1,1,0)
(1,2,0)
(1,3,2)
(1,4,4)
(1,5,1)
答案 0 :(得分:1)
您不需要CTE。在数据库中创建Numbers表。 Numbers表只是一个表,其中包含从0到某个任意大数的连续整数的单个列(我的目标是9999)。将它留在数据库中,因为它对各种事物都很有用。
create table Numbers(Number int)
insert Numbers
SELECT TOP 10000 row_number() over(order by t1.number) -1 as N
FROM master..spt_values t1
CROSS JOIN master..spt_values t2
现在您可以运行如下查询:
insert TraineeForecast(I, X, Signups)
select ni.Number I, nx.Number + 1 X, tc.Signups - tc.Signups * @withdrawlConstant Signups
from Numbers ni
cross join Numbers nx
left outer join TraineeCredits tc on tc.I = ni.Number and tc.X = nx.Number
where ni.Number between 0 and 12
and nx.Number between 1 and 24
and nx.Number > ni.Number
交叉连接为I和X的每个组合生成一个结果,可以将它们连接到您的TraineeCredits表以获得注册。
在此处查看SQLFiddle:http://sqlfiddle.com/#!3/e6994/1
答案 1 :(得分:0)
你可以生成两个循环&#39;以这种方式递归cte:
WITH r AS (
SELECT 1 AS n, 1 AS m
UNION ALL
SELECT CASE WHEN m<24 THEN n ELSE n+1 END,
CASE WHEN m<24 THEN m+1 ELSE 1 end
FROM r WHERE n*m<288
)
SELECT * FROM r
OPTION (MAXRECURSION 0)
答案 2 :(得分:0)
事实上,您可以通过CTE实现数据插入。
WITH i_values as
(
SELECT 0 as i
UNION ALL
SELECT i_values.i+1
FROM i_values
WHERE i_values.i <= 11
),
x_values as
(
SELECT 0 as x
UNION ALL
SELECT x_values.x+1
FROM x_values
WHERE x_values.x <= 23
)
, i_x_values as
(
SELECT i_values.i, x_values.x
FROM i_values
FULL OUTER JOIN x_values
ON x_values.x >= i_values.i - 1
)
INSERT INTO TraineeForecast
SELECT i_x_values.I, (i_x_values.X)+1, TraineeCredits.Signups - TraineeCredits.Signups * 0.25
FROM TraineeCredits
INNER JOIN i_x_values
ON TraineeCredits.I = i_x_values.I AND TraineeCredits.X = i_x_values.X;
这是 SQL Fiddle demo 。