2

(一个“它是如何工作的” - 问题)

假设我有这张桌子:

   Id            val
    ------------------
    1             a       <--
    1             a
    1             a
    2             b       <--
    2             b
    2             b

现在假设我想要标记的行:

我可以指望这个查询:

select id,val from (
select id , val , row_number() over (partition by id order by id) as rn
) k where rn=1

给我选定的行?

(注意order by条款)。它会将订单视为插入的订单吗?

4

2 回答 2

2

不保证该行为。您的查询将返回两行,但哪些是未定义的。

当我尝试

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

结果是可变的,具体取决于插入的顺序,但与第一个插入的行不一致。

于 2012-09-13T08:47:40.653 回答
2

不,行的顺序只能由ORDER BY子句确定 - 如果您的ORDER BY子句在两行之间不是确定性的,那么它们返回的顺序是任意的。您需要添加一些东西来使它们唯一化才能做到这一点。但是,作为一般规则,大多数表都应该有一个唯一键或主键 - 从而为您提供可以订购的东西。

各种因素都会影响它,例如企业版中的旋转木马扫描、聚集索引的重新索引等。

于 2012-09-13T08:48:50.620 回答