假设您有一个包含非唯一值的表,例如:
$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
答案 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
它仍然是一个窗口功能,但不确定这是否重要。
答案 2 :(得分:-1)
MySQL的:
SELECT @rownum := @rownum + 1 AS rank, a.*
FROM accounts a,(SELECT @rownum := 0) r;
在ORACLE中它只是
SELECT ROWNUM, a.*
FROM accounts a;
两个没有窗口