7

I have a simple join table with two id columns in SQL Server. Is there any way to select all rows in the exact order they were inserted?

If I try to make a SELECT *, even if I don't specify an ORDER BY clause, the rows are not being returned in the order they were inserted, but ordered by the first key column.

I know it's a weird question, but this table is very big and I need to check exactly when a strange behavior has begun, and unfortunately I don't have a timestamp column in my table.

UPDATE #1

I'll try to explain why I'm saying that the rows are not returned in 'natural' order when I SELECT * FROM table without an ORDER BY clause.

My table was something like this:

id1     id2
---------------
  1       1
  2       2
  3       3
  4       4
  5       5
  5       6

... and so on, with about 90.000+ rows

Now, I don't know why (probably a software bug inserted these rows), but my table have 4.5 million rows and looks like this:

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)

Crazy, my table have now millions of rows. I have to take a look when this happened (when the rows where inserted) because I have to delete them, but I can't just delete using *WHERE id2 IN (strange_ids)* because there are "right" id1 columns that belongs to these id2 columns, and I can't delete them, so I'm trying to see when exactly these rows were inserted to delete them.

When I SELECT * FROM table, it returns me ordered by id1, like the above table, and the rows were not inserted in this order in my table. I think my table is not corrupted because is the second time that this strange behavior happens the same way, but now I have so many rows that I can delete manually like it was on 1st time. Why the rows are not being returned in the order they were inserted? These "strange rows" were definetely inserted yesterday and should be returned near the end of my table if I do a SELECT * without an ORDER BY, isn't it?

4

4 回答 4

14

A select query with no order by does not retrieve the rows in any particular order. You have to have an order by to get an order.

SQL Server does not have any default method for retrieving by insert order. You can do it, if you have the information in the row. The best way is a primary key identity column:

TableId int identity(1, 1) not null primary key

Such a column is incremented as each row is inserted.

You can also have a CreatedAt column:

CreatedAt datetime default getdate()

However, this could have duplicates for simultaneous inserts.

The key point, though, is that a select with no order by clause returns an unordered set of rows.

于 2013-06-27T14:28:26.643 回答
6

正如其他人已经写的那样,您将无法按照插入的顺序将行从链接表中取出。

如果此链接表正在加入的一个或两个表中的行存在某种内部排序,那么您可以使用它来尝试确定链接表行的创建时间。基本上,它们不能在创建包含 PK:s 的两行之前创建。

但另一方面,您将无法知道它们创建后多长时间。

如果您有不错的备份,您可以尝试恢复一个或几个不同年龄的备份,然后尝试查看这些备份是否也包含这种奇怪的行为。它至少可以给你一些关于奇怪什么时候开始的线索。

但最重要的是,只使用一个选择,现在有一种方法可以按照插入的顺序将行从这样的表中取出。

于 2013-06-27T15:07:01.830 回答
5

如果 SELECT * 没有以“自然”顺序返回它们,并且您没有使用时间戳或自动递增 ID 插入它们,那么我相信您已经沉没了。如果您有一个 IDENTITY 字段,请按此排序。但是我的问题是,你怎么知道 SELECT * 没有按照插入的顺序返回它们?

更新:根据您的更新,似乎没有方法可以按您的意愿返回记录,我猜您在 ID1 上有一个聚集索引?

于 2013-06-27T14:27:41.440 回答
2
Select *, %%physloc%% as pl from table
order by pl desc
于 2015-12-14T11:54:46.843 回答