问题
(a "How it works" - question)
Suppose I have this table :
Id val
------------------
1 a <--
1 a
1 a
2 b <--
2 b
2 b
Now lets say I want the marked rows :
Can I count on this query :
select id,val from (
select id , val , row_number() over (partition by id order by id) as rn
) k where rn=1
to give me the Selected rows ?
(notice the order by
clause). will it consider the order as the order they were inserted ?
回答1:
The behaviour is not guaranteed. Your query will return two rows, but which ones is undefined.
When I experiment with
create table #t (id int, val char(1), t timestamp)
insert #t (id, val) values (1,'a')
insert #t (id, val) values (1,'a')
insert #t (id, val) values (2,'b')
insert #t (id, val) values (1,'a')
insert #t (id, val) values (2,'b')
insert #t (id, val) values (2,'b')
select * from #t
select * from (
select *, row_number() over (partition by id order by id) as rn from #t
) k where rn=1
drop table #t
the results are variable, depending on the order of insertion, but not consistently the first inserted rows.
回答2:
No, the order of rows can only be determined by the ORDER BY
clause - and if your ORDER BY
clause isn't deterministic between two rows, then the order that they are returned in is arbitrary. You would need to add something to uniquify them in order to be able to do that. However, as a general rule, most tables should have a unique or primary key - thereby giving you something that you could order by.
Various things can affect it, such as merry-go-round scans in Enterprise edition, reindexing of a clustered index, etc.
来源:https://stackoverflow.com/questions/12402524/does-sql-server-minds-the-way-records-where-inserted