如何在SQL中压缩数字列表

时间:2019-10-04 15:24:38

标签: sql-server tsql

我有一张表,其中有一个int列。这些数字都是唯一的,但并非全部都出现在从最小(1)到最大的范围内。我想“压缩”数字列表,以便列表中的最大数字是列表中数字的COUNT,并且记录保持相同的相对顺序(将其视为Identity列) ,但实际上不是)。所以例如,如果我有数字

1 3 5 6 10 11 14 15 20 30

我希望他们重新编号

1 2 3 4 5 6 7 8 9 10

其中3变为2,5变为3,依此类推。如何在T-SQL中做到这一点?

4 个答案:

答案 0 :(得分:3)

我想您只需要row_number()

    SELECT row_number() 
     over
  (partition by column order by column 
   asc) rn from table;

答案 1 :(得分:3)

Himanshu的位置为row_number(),已经为+1。

但是,以防万一您希望执行 UPDATE ...可以通过CTE完成

示例

;with cte as (
    Select *
          ,NewValue = row_number() over (order by SomeCol)
     from YourTable
)
Update cte set SomeCol=NewValue

答案 2 :(得分:1)

您提到数字已经是唯一的, 使用以下替代方法-

IF OBJECT_ID('TEMPDB..#SampleTable') IS NOT NULL DROP TABLE #SampleTable

Create table #SampleTable (num int)

insert into #SampleTable values (1),(3),(5),(6),(10),(11),(14),(15),(20),(30)

--Alternate Methods
select num,
row_number() over (order by num) as [ROW_NUMBER],
rank() over (order by num) as [RANK],
dense_rank() over (order by num) as [DENSE_RANK]
from #SampleTable

答案 3 :(得分:0)

在旁注。您可以将ROW_NUMBER()视为行的总数。您可以看到它们都做同样的事情:

WITH numbers AS (SELECT f.G, f.N FROM (VALUES (1,1),(1,3),(1,4),(2,1),(2,5)) AS f(G,N))
SELECT 
  NbrGroup = f.G,
  OldNbr   = f.N,
  NewNbrRN = ROW_NUMBER() OVER (PARTITION BY f.G ORDER BY f.N),
  NewNbrC  = COUNT(*)     OVER (PARTITION BY f.G ORDER BY f.N)
FROM numbers AS f;

结果:

NbrGroup    OldNbr      NewNbrRN             NewNbrC
----------- ----------- -------------------- -----------
1           1           1                    1
1           3           2                    2
1           4           3                    3
2           1           1                    1
2           5           2                    2

ROW_NUMBER()的性能更好,这就是为什么开发人员不将COUNT用于此类事物的原因。