我有一个简单的连接表,在SQL Server中有两个id列。 有没有办法按照插入的确切顺序选择所有行?
如果我尝试创建SELECT *,即使我没有指定ORDER BY子句,也不会按插入顺序返回行,而是按第一个键列排序。
我知道这是一个奇怪的问题,但是这个表非常大,我需要确切地检查一下奇怪的行为何时开始,不幸的是我的表中没有时间戳列。
更新#1
我将尝试解释为什么我说当没有ORDER BY子句的SELECT * FROM表时,行不会以'自然'顺序返回。
我的桌子是这样的:
id1 id2
---------------
1 1
2 2
3 3
4 4
5 5
5 6
... and so on, with about 90.000+ rows
现在,我不知道为什么(可能是软件错误插入了这些行),但我的表有450万行,看起来像这样:
id1 id2
---------------
1 1
1 35986
1 44775
1 60816
1 62998
1 67514
1 67517
1 67701
1 67837
...
1 75657 (100+ "strange" rows)
2 2
2 35986
2 44775
2 60816
2 62998
2 67514
2 67517
2 67701
2 67837
...
2 75657 (100+ "strange" rows)
疯狂,我的桌子现在有数百万行。我必须看一下当发生这种情况时(当插入的行时),因为我必须删除它们,但我不能只使用* WHERE id2 IN(strange_ids)*删除因为有“right”id1列属于这些id2列,我无法删除它们,因此我试图查看何时插入这些行以删除它们。
当我SELECT * FROM table时,它返回我按id1排序,如上表所示,和 在我的表中没有按此顺序插入行。我认为我的表没有被破坏,因为这是第二次这种奇怪的行为以同样的方式发生,但现在我有这么多行,我可以像第一次那样手动删除。为什么行不按插入顺序返回?这些“奇怪的行”昨天被定义插入,如果我在没有ORDER BY的情况下执行SELECT *,应该在我的表的末尾返回,不是吗?
答案 0 :(得分:13)
没有select
的{{1}}查询不以任何特定顺序检索行。您必须有order by
才能获得订单。
SQL Server没有任何默认方法可以按插入顺序进行检索。如果您有行中的信息,则可以执行此操作。最好的方法是主键标识列:
order by
在插入每一行时,这样的列会递增。
您还可以拥有TableId int identity(1, 1) not null primary key
列:
CreatedAt
但是,这可能会同时插入重复项。
关键的一点是,CreatedAt datetime default getdate()
没有select
子句会返回一组无序的行。
答案 1 :(得分:6)
正如其他人已经写过的那样,您将无法按照插入顺序从链接表中获取行。
如果此链接表加入的一个或两个表中存在某种行的内部排序,那么您可以使用它来尝试找出链接表行的时间已创建。基本上,它们不能被创建 BEFORE 已经创建了包含PK:s的两个行。
但另一方面,在创建之后,你将无法找到多长时间。
如果你有不错的备份,你可以尝试恢复一个或几个不同年龄的备份,然后尝试查看这些备份是否也包含这个奇怪的行为。它可以给你至少一些关于陌生感何时开始的线索。
但最重要的是,只使用一个选择,现在可以按照插入的顺序从这样的表中获取行。
答案 2 :(得分:5)
如果SELECT *没有按照“自然”顺序返回它们而你没有插入时间戳或自动递增ID,那么我相信你已经沉没了。如果您有IDENTITY字段,请按此顺序排序。 但我的问题是,你如何判断SELECT *没有按照它们插入的顺序返回它们?
更新: 根据您的更新,看起来没有方法可以根据需要返回记录,我猜你在ID1上有一个聚集索引?
答案 3 :(得分:2)
Select *, %%physloc%% as pl from table
order by pl desc