Sql 如何在选择中创建while循环?
我有两个专栏 我想输出如下查询 我尝试在SQL中使用循环,但未能输出查询Sql 如何在选择中创建while循环?,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有两个专栏 我想输出如下查询 我尝试在SQL中使用循环,但未能输出查询 我的问题是:如何按[Total]列中的数字重复[Name]列中的值?这通常通过递归子查询处理。但是,在名称重复的情况下,我导出了一个行顺序,最好使用唯一键 MS SQL Server 2017架构设置: 问题1: : 你可以做得比公认的答案简单得多 我建议创建一个带有顺序正整数的数字表 CREATE TABLE dbo.Numbers(Number INT PRIMARY KEY); INSERT INTO dbo.Nu
我的问题是:如何按[Total]列中的数字重复[Name]列中的值?这通常通过递归子查询处理。但是,在名称重复的情况下,我导出了一个行顺序,最好使用唯一键 MS SQL Server 2017架构设置: 问题1: :
你可以做得比公认的答案简单得多 我建议创建一个带有顺序正整数的数字表
CREATE TABLE dbo.Numbers(Number INT PRIMARY KEY);
INSERT INTO dbo.Numbers
SELECT TOP 10000 ROW_NUMBER() OVER (ORDER BY @@SPID)
FROM sys.all_objects o1,
sys.all_objects o2
然后在数字上加入你的封闭式问题
CREATE TABLE #Test1(
[ID] [int] NULL,
[Cnt] [varchar](50) NULL
) ON [PRIMARY]
GO
CREATE TABLE #Test2(
[ID] [int] NULL,
[col1] [varchar](50) NULL,
[col2] [varchar](50) NULL,
[col3] [varchar](50) NULL
) ON [PRIMARY]
GO
CREATE TABLE #Test3(
[ID1] [int] NULL,
Cnt int,
Id2 int,
[col1] [varchar](50) NULL,
[col2] [varchar](50) NULL,
[col3] [varchar](50) NULL
) ON [PRIMARY]
GO
INSERT INTO #TEST1 (ID, Cnt) VALUES (1, 2)
INSERT INTO #TEST1 (ID, Cnt) VALUES (2, 3)
INSERT INTO #TEST1 (ID, Cnt) VALUES (3, 1)
INSERT INTO #TEST1 (ID, Cnt) VALUES (4, 2)
INSERT INTO #TEST1 (ID, Cnt) VALUES (5, 1)
INSERT INTO #TEST1 (ID, Cnt) VALUES (6, 4)
INSERT INTO #TEST2 (ID, Col1, Col2, Col3) VALUES (1, 'a1', 'b1', 'c1')
INSERT INTO #TEST2 (ID, Col1, Col2, Col3) VALUES (2, 'a2', 'b2', 'c2')
INSERT INTO #TEST2 (ID, Col1, Col2, Col3) VALUES (3, 'a3', 'b3', 'c3')
INSERT INTO #TEST2 (ID, Col1, Col2, Col3) VALUES (4, 'a4', 'b4', 'c4')
INSERT INTO #TEST2 (ID, Col1, Col2, Col3) VALUES (5, 'a5', 'b5', 'c5')
INSERT INTO #TEST2 (ID, Col1, Col2, Col3) VALUES (6, 'a6', 'b6', 'c6')
declare @a int = 1, @b int, @c int = 0;
while @a <= (select MAX(Id) from #Test1)
begin
set @b = (select Cnt from #Test1 where ID = @a);
set @c = 0;
while @c < @b begin
insert into #Test3 (ID1, Cnt, Id2, col1, col2, col3) select @a, @b, @a, col1, col2, col3 from #Test2 where ID = @a;
set @c += 1;
end
SET @a += 1;
end
select * from #Test3 order by 1, 2;
如果您发布代码或错误消息的图像,请确保您也将实际的代码/消息复制粘贴或直接键入到帖子中-请注意,您不能在普通SQL中使用循环。这在过程SQL中可用。您需要的可以通过使用递归查询和一些计算来实现。ok how???……您是如何获得初始sql结果的?显示累计totalok的表我需要我想根据[total]Msg 208列16级状态1中的现有数字多次执行该语句,第1行对象名称“STRING_SPLIT”无效。我们的许多生产系统都是SQL 2016之前的。不过,这确实会减少查询的冗长程度。@MahmoudMagdyMousaa-将添加数字表示例的代码,然后语句终止。最大递归100在语句完成之前已用尽。最大100行>>>>>>>>>>>在查询后添加选项MAXRECURSION 0。有32767个递归帧的限制。
| name | instance | total | OriginalTotal | running_total |
|---------|----------|-------|---------------|---------------|
| ahmed | 1 | 1 | 3 | 1 |
| ahmed | 1 | 1 | 3 | 2 |
| ahmed | 1 | 1 | 3 | 3 |
| mahmoud | 2 | 1 | 2 | 1 |
| mahmoud | 2 | 1 | 2 | 2 |
| ahmed | 3 | 1 | 5 | 1 |
| ahmed | 3 | 1 | 5 | 2 |
| ahmed | 3 | 1 | 5 | 3 |
| ahmed | 3 | 1 | 5 | 4 |
| ahmed | 3 | 1 | 5 | 5 |
CREATE TABLE dbo.Numbers(Number INT PRIMARY KEY);
INSERT INTO dbo.Numbers
SELECT TOP 10000 ROW_NUMBER() OVER (ORDER BY @@SPID)
FROM sys.all_objects o1,
sys.all_objects o2
SELECT name, 1 AS total
FROM Names nam
JOIN dbo.Numbers num ON num.Number <= nam.total;
SELECT name, 1 AS total
FROM Names
CROSS APPLY STRING_SPLIT(SPACE(total - 1), ' ')
CREATE TABLE #Test1(
[ID] [int] NULL,
[Cnt] [varchar](50) NULL
) ON [PRIMARY]
GO
CREATE TABLE #Test2(
[ID] [int] NULL,
[col1] [varchar](50) NULL,
[col2] [varchar](50) NULL,
[col3] [varchar](50) NULL
) ON [PRIMARY]
GO
CREATE TABLE #Test3(
[ID1] [int] NULL,
Cnt int,
Id2 int,
[col1] [varchar](50) NULL,
[col2] [varchar](50) NULL,
[col3] [varchar](50) NULL
) ON [PRIMARY]
GO
INSERT INTO #TEST1 (ID, Cnt) VALUES (1, 2)
INSERT INTO #TEST1 (ID, Cnt) VALUES (2, 3)
INSERT INTO #TEST1 (ID, Cnt) VALUES (3, 1)
INSERT INTO #TEST1 (ID, Cnt) VALUES (4, 2)
INSERT INTO #TEST1 (ID, Cnt) VALUES (5, 1)
INSERT INTO #TEST1 (ID, Cnt) VALUES (6, 4)
INSERT INTO #TEST2 (ID, Col1, Col2, Col3) VALUES (1, 'a1', 'b1', 'c1')
INSERT INTO #TEST2 (ID, Col1, Col2, Col3) VALUES (2, 'a2', 'b2', 'c2')
INSERT INTO #TEST2 (ID, Col1, Col2, Col3) VALUES (3, 'a3', 'b3', 'c3')
INSERT INTO #TEST2 (ID, Col1, Col2, Col3) VALUES (4, 'a4', 'b4', 'c4')
INSERT INTO #TEST2 (ID, Col1, Col2, Col3) VALUES (5, 'a5', 'b5', 'c5')
INSERT INTO #TEST2 (ID, Col1, Col2, Col3) VALUES (6, 'a6', 'b6', 'c6')
declare @a int = 1, @b int, @c int = 0;
while @a <= (select MAX(Id) from #Test1)
begin
set @b = (select Cnt from #Test1 where ID = @a);
set @c = 0;
while @c < @b begin
insert into #Test3 (ID1, Cnt, Id2, col1, col2, col3) select @a, @b, @a, col1, col2, col3 from #Test2 where ID = @a;
set @c += 1;
end
SET @a += 1;
end
select * from #Test3 order by 1, 2;