我有这个查询:
#create table #tmp_table( n_progressive int , name char(10),
id_numeric(11,0) )
declare @i int = 0 declare @c int declare n_progressive int = 0
declare @var_table table ( name char(10), id_number numeric(11,0) )
insert into @var_table( name, id_number ) select name,id_number from MainTable
select @c= count (*) from @var_table
while(@i<@c) begin set @n_progressive = @n_progressive + 1
insert into #Tmptable( n_progressive , name , id_numeric ) select @n_progressive ,name,id_numeric from @var_table
end
var_table中的记录为4。对于每条记录,我希望n_progressive递增+1。
上面的查询结果是这样:
+--------------+----------+------------+
|n_progressive | name | numeric_id |
+--------------+----------+------------+
|1 | RM1 | 1 |
|1 | RM2 | 2 |
|1 | RM3 | 3 |
|1 | RM4 | 4 |
|2 | RM1 | 1 |
|2 | RM2 | 2 |
|2 | RM3 | 3 |
|2 | RM4 | 4 |
|3 | RM1 | 1 |
|3 | RM2 | 2 |
|3 | RM3 | 3 |
|3 | RM4 | 4 |
|4 | RM1 | 1 |
|4 | RM2 | 2 |
|4 | RM3 | 3 |
|4 | RM4 | 4 |
+--------------+----------+------------+
我想要的是:
+---------------+----------+-------------+
|n_progressive | name | numeric_id |
+---------------+----------+-------------+
|1 | RM1 | 1 |
|2 | RM2 | 2 |
|3 | RM3 | 3 |
|4 | RM4 | 4 |
+---------------+----------+-------------+
我不想使用游标。
答案 0 :(得分:3)
您要在循环的每次迭代中从@var_table
中选择所有记录,这就是为什么您将所有记录乘以4(@var_table
中的记录数)的原因。
但是,您根本不需要循环,无论如何,无论何时使用SQL都应努力避免循环,因为SQL最好使用基于集合的方法而非程序方法(有关更多信息,请阅读RBAR: ‘Row By Agonizing Row’和What is RBAR? How can I avoid it?)
您可以简单地使用row_number()
窗口函数来获取n_progressive
值,而不是循环:
insert into #Tmptable( n_progressive, name, id_numeric)
select row_number() over(order by name), name, id_numeric
from @var_table
答案 1 :(得分:3)
您并没有限制INSERT从源表中读取一行,而是要多次复制 整个 表。要直接 修复您正在 尝试 要做的事情,您应该执行以下操作……
while(@i<@c) begin
set @n_progressive = @n_progressive + 1
insert into
#Tmptable( n_progressive , name , id_numeric )
select
@n_progressive, name, id_numeric
from
@var_table
WHERE
id_number = @i -- Only one row
SET @i = @i + 1 -- Move to the next row
end
一个更好的主意是使用ROW_NUMBER()
,从而避免使用循环和其他许多样板代码。
insert into
#Tmptable( n_progressive , name , id_numeric )
select
ROW_NUMBER() OVER (ORDER BY id_numeric),
name,
id_numeric
from
@var_table
一个更好的主意仍然是使用一个标识列,然后让表格进行数字分配。
create table
#tmp_table(
n_progressive int IDENTITY(1,1),
name char(10) ,
id_ numeric(11,0)
)
insert into #Tmptable(name , id_numeric )
select name, id_numeric
from MainTable
ORDER BY id_numeric
答案 2 :(得分:0)
这是您想要的吗?
with n as (
select 1 as n
union all
select n + 1
from n
where n < @n_limit
)
select n.n, name + cast(n.n as varchar(255)), n.n as numeric_id
from n
option (maxrecursion 0);