0

我有这个查询:

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

我不想使用光标。

4

3 回答 3

3

您正在从@var_table循环的每次迭代中选择所有记录,这就是为什么您将所有记录乘以 4(中的记录数@var_table)。

但是,您根本不需要循环,并且无论如何在使用 SQL 时都应该努力避免循环,因为 SQL 最适用于基于集合的方法而不是过程方法(有关更多信息,请阅读RBAR:' Row By Agonizing Row'</a> 和RBAR 是什么?如何避免?

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
于 2018-08-21T11:05:33.603 回答
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
于 2018-08-21T11:05:47.943 回答
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);
于 2018-08-21T10:59:27.370 回答