Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 用于两个循环的SQL Server CTE增量函数?_Sql Server_Sql Server 2008_Tsql - Fatal编程技术网

Sql server 用于两个循环的SQL Server CTE增量函数?

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

目前,我在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
在下一个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;