不使用ROW_NUMBER窗口函数的行号

时间:2018-02-16 20:14:35

标签: sql-server tsql row-number

假设您有一个包含非唯一值的表,例如:

$last_name

现在使用ROW_NUMBER函数,您可以获得唯一的递增行号。

CREATE TABLE accounts ( fname VARCHAR(20), lname VARCHAR(20)) 
GO 

INSERT accounts VALUES ('Fred', 'Flintstone') 
INSERT accounts VALUES ('Fred', 'Flintstone') 
INSERT accounts VALUES ('Fred', 'Flintstone') 

SELECT * FROM accounts 
GO

但是如何在不使用ROW_NUMBER函数的情况下实现这一点。我尝试使用NEWID()给每一行一个唯一的ID,然后计算下面给出的行,但是它不起作用,因为它给了我一个不以1开头的非唯一数字。 请注意,我不想更改表以添加新列。

select *, ROW_NUMBER() over(order by (select null)) as rn
from accounts

用于玩弄的SQL小提琴是http://sqlfiddle.com/#!18/c270f/3/0

3 个答案:

答案 0 :(得分:2)

以下说明了您的代码失败的原因,但未提供Row_Number()的替代方法。

TopId已添加到最终select,该列应获取NewId()生成的最小值,并在每一行中报告。而是为每一行生成一个新值。

-- Sample data.
declare @Samples as Table ( FName VarChar(20), LName VarChar(20) );
insert into @Samples ( FName, LName ) values
  ( 'Fred', 'Flintstone' ), ( 'Fred', 'Flintstone' ), ( 'Fred', 'Flintstone' );
select * from @Samples;

-- Cross apply   NewId()   in a CTE.
;with cte as
  ( select *
      from @Samples as S
    cross apply ( select NewId() ) as Ph( Id ) )
  select *, ( select count(*) from cte as c1 where c1.Id >= c.Id ) as RN,
    -- The following column should output the minimum   Id   value from the table for every row.
    --   Instead, it generates a new unique identifier for each row.
    ( select top 1 id from cte order by id ) as TopId
    from cte as c
    order by RN;

执行计划显示CTE被视为正在重复评估的视图,从而产生相互冲突的Id值。

答案 1 :(得分:0)

这个怎么样:

SELECT 
  src.*, 
  SUM(DummyVal) OVER(ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS RowId
FROM (
  SELECT a.*, 1 AS DummyVal
  FROM MyTable a
) src

它仍然是一个窗口功能,但不确定这是否重要。

Fiddle me this

答案 2 :(得分:-1)

MySQL的:

SELECT @rownum := @rownum + 1 AS rank, a.* 
FROM accounts a,(SELECT @rownum := 0) r;

在ORACLE中它只是

SELECT ROWNUM, a.*
FROM accounts a;

两个没有窗口