为每个记录增加一个变量

时间:2018-08-21 10:56:04

标签: sql sql-server tsql

我有这个查询:

#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         | 
+---------------+----------+-------------+

我不想使用游标。

3 个答案:

答案 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);