Sql server 用于两个循环的SQL Server CTE增量函数?
目前,我在SQL Server 2008中具有以下循环函数:Sql server 用于两个循环的SQL Server CTE增量函数?,sql-server,sql-server-2008,tsql,Sql Server,Sql Server 2008,Tsql,目前,我在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 Tr
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
在下一个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)
你不需要CTE。在数据库中创建数字表。一个数字表就是一个包含从0到某个任意大数字的顺序整数的单列表。将它保留在数据库中,因为它对各种事情都很有用
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的每个组合生成一个结果,该结果可以联接到您的TraineCredits表以获得注册
在这里查看SQLFIDLE:您可以通过以下方式使用递归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)
实际上,您可以通过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;
这是一个。速度非常慢-我不知道为什么。最里面的语句执行不到13*25次,而且许多选择和插入实际上根本不需要任何时间。这段代码需要多长时间才能运行?对不起,我对推送问题感到非常困惑。您正在显示的行是TraineCredits表中的行,还是查询返回的行?让我们简化这个问题,假设我从0到3,X从1到5,X永远不是0,对吗?。当我运行我的查询时,结果是:0、1、20、2、40、3、10、4、30、5、11、2、11、3、51、4、41、5、42、3、32、4、12、5、23、4、23、23、5、1结果应该是什么?我只是在这里编注册值?看起来真的很好。我将运行查询并继续返回更多反馈。我实际上有一个fn_NumgeneratorOkay,它似乎在工作,但我还有最后一个查询。如果我想向下推注册值,即如果我们有以下情况:I,X,通过推注册0,1,2 0,2,4 0,3,1,我想做以下事情:1,1,0 1,2,2 1,3,4 1,4 1,1如何实现?这需要完全其他的东西吗?我不明白你在做什么。你能澄清一下吗?也许可以编辑这个问题,这样你就有了更多的空间和格式。所以当我为0时,X从1变为24。当我是1时,X从2变为24。当I为n时,X从n+1变为24。你的意思是要用零填充X在0和n之间的行吗?是的,然后向下推数值。因此,如果X=0,I=0,注册数=120,那么I=1,X=1也是120,而I=1,X=0是0。这是迄今为止我所看到的CTE函数工作的最清晰的例子。谢谢如果你能解释下一行:ON x_values.x>=i_values.i-1,那太好了。不客气!首先,我计算出您使用的I和x值的迭代次数。您可以在更新的fiddle中检查值-当然!首先,我使用代码中的原始WHILE循环手动计算I和x值。我看到I的值在0到12之间,x的值在I-1到24之间。所以,当i=12时,x从11变为24。因此,x_values.x>=i_values.i-1的条件我有一个问题:基本上,如果我插入到TraineeCredits而不是TraineeForecast,选择是否会受到影响?i、 它是自我参照
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;