Sql server SQL server程序中带表的循环
我的预期结果很难解释,所以这里我展示了示例数据 SourceTable:我在HeadNo列中有字母表 从这个源表中,我想创建一种循环结果,其中每个HeadNo将返回10000个结果,从0000到9999 结果应该如下所示: 每个人头上都有智慧吗 我想合并并插入到一个单独的表中。如果每一行都需要0-9999的值,则只需交叉连接到一个理货表:Sql server SQL server程序中带表的循环,sql-server,loops,join,foreach,sql-server-2012,Sql Server,Loops,Join,Foreach,Sql Server 2012,我的预期结果很难解释,所以这里我展示了示例数据 SourceTable:我在HeadNo列中有字母表 从这个源表中,我想创建一种循环结果,其中每个HeadNo将返回10000个结果,从0000到9999 结果应该如下所示: 每个人头上都有智慧吗 我想合并并插入到一个单独的表中。如果每一行都需要0-9999的值,则只需交叉连接到一个理货表: WITH N AS( SELECT * FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NUL
WITH N AS(
SELECT *
FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL)) N(N)),
Tally AS(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1 AS I
FROM N N1
CROSS JOIN N N2 --100
CROSS JOIN N N3 --1000
CROSS JOIN N N4 --10000
)
SELECT YT.HeadNo,
YT.HeadNo + RIGHT('0000' + CONVERT(varchar(4),T.I),4) AS ActualCode
FROM YourTable YT
CROSS JOIN Tally T;
但是,如果每个HeadNo都有实际的开始和结束范围,如下面的示例所示,则需要在联接中使用更多的逻辑:
第二个示例假设HeadNo的格式始终为AA0000;如果没有,那么我们就缺少了应该包含在您的问题中的重要信息。请尝试下面的代码。我使用递归CTE从0到9999获取numebrs,然后交叉连接到HeadNo列:
实际代码的值是否始终采用AA0000格式?@Cid:ya我更改了第一行的输出,@Larnu:yes,格式将始终采用2个首字母和4个数字。。像AA0000到ZZ9999一样,这不会给出预期的结果。OP需要格式为“AA0000”的字符串。强制转换为varchar4的int值0是值“0”,给出最终结果“AA0”。同样,这样的CTE是RBAR的一种隐藏形式;理货表将避免对选项MAXRECURSION 0的要求,并可能提供性能优势。@MichałTurczyn使用Order by获得预期结果。非常感谢,您的上述查询按照我的要求进行。
HeadNo | Actual Code
---------+---------------
AA | AA0000
AA | AB0001
AA | AC0002
AA | AD0003
--------------------
--------------------
------- so on ------
AA | AA9998
AA | AA9999
ZZ | ZZ0000
ZZ | ZZ0001
ZZ | ZZ0002
ZZ | ZZ0003
--------------------
--------------------
------- so on ------
ZZ | ZZ9999
WITH N AS(
SELECT *
FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL)) N(N)),
Tally AS(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1 AS I
FROM N N1
CROSS JOIN N N2 --100
CROSS JOIN N N3 --1000
CROSS JOIN N N4 --10000
)
SELECT YT.HeadNo,
YT.HeadNo + RIGHT('0000' + CONVERT(varchar(4),T.I),4) AS ActualCode
FROM YourTable YT
CROSS JOIN Tally T;
WITH VTE AS (
SELECT *
FROM (VALUES('AA','AA0000','AA9999'),
('AB','AB0000','AB5000'), --Guesssing this is more realistic
('AC','AC1000','AC8000'),
('AD','AD0000','AD0100'),
('ZZ','ZZ0000','ZZ9999')) V(HeadNo, HeadStart, HeadEnd)),
N AS(
SELECT *
FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL)) N(N)),
Tally AS(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1 AS I
FROM N N1
CROSS JOIN N N2 --100
CROSS JOIN N N3 --1000
CROSS JOIN N N4 --10000
)
SELECT V.HeadNo,
V.HeadNo + RIGHT('0000' + CONVERT(varchar(4),T.I),4) AS ActualCode
FROM VTE V
JOIN Tally T ON T.I BETWEEN STUFF(V.HeadStart,1,2,'') AND STUFF(V.HeadEnd,1,2,'')
ORDER BY V.HeadNo,
ActualCode;
;with cte as (
select 0 n
union all
select n + 1 from cte
where n < 9999
)
select HeadNo, HeadNo + right('0000' + cast(n as varchar(4)), 4) from MyTable
cross join cte option (maxrecursion 0)