(“如何运作” - 问题)
假设我有这张表:
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
子句)。它会将订单视为插入订单吗?
答案 0 :(得分: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
结果是可变的,具体取决于插入顺序,但不是第一次插入的行。
答案 1 :(得分:2)
不,行的顺序只能由ORDER BY
子句确定 - 如果您的ORDER BY
子句在两行之间不确定,则它们返回的顺序是任意的。你需要添加一些东西来统一它们才能做到这一点。但是,作为一般规则,大多数表应该具有唯一或主键 - 从而为您提供可以订购的内容。
可能会影响它,例如企业版中的旋转木马扫描,聚簇索引的重建索引等。