我有一个包含800,000个没有主键的条目的表。我不允许添加主键,我不能按 TOP 1排序.... ORDER BY DESC因为完成此任务需要数小时。所以我尝试了这个工作:
DECLARE @ROWCOUNT int, @OFFSET int
SELECT @ROWCOUNT = (SELECT COUNT(field) FROM TABLE)
SET @OFFSET = @ROWCOUNT-1
select TOP 1 FROM TABLE WHERE=?????NO PRIMARY KEY??? BETWEEN @Offset AND @ROWCOUNT
当然这不起作用。
无论如何要使用此代码/或更好的代码来检索表中的最后一行?
答案 0 :(得分:4)
如果您的表没有主键或您的主键不是有序...您可以尝试下面的代码...如果您想查看更多的最后一条记录,您可以更改代码中的数字
Select top (select COUNT(*) from table) * From table
EXCEPT
Select top ((select COUNT(*) from table)-(1)) * From table
答案 1 :(得分:2)
您需要添加一个索引,可以吗?
即使您没有主键,索引也会大大加快查询速度。
你说你没有主键,但是对于你的问题,我假设你在表上有某种类型的时间戳或类似的东西,如果你使用这个列创建一个索引,你将能够执行像这样的查询:
SELECT *
FROM table_name
WHERE timestamp_column_name=(
SELECT max(timestamp_column_name)
FROM table_name
)
答案 2 :(得分:2)
如果您需要从800,000行的表中选择1列,其中该列是最小或最大可能值,并且该列未编入索引,那么无懈可击的事实是SQL必须读取表中的每一行为了识别最小值或最大值。
(除此之外,从表面上读取800,000行表的所有行不应该花那么长时间。列有多宽?查询运行的频率是多少?是否有并发,锁定,阻塞,或死锁问题?这些可能是可以解决的痛点。搁置一边。)
有许多解决方法(索引,视图,索引视图,talbe的peridocial索引副本,在刷新之前运行一次存储结果使用T段时间等),但实际上所有这些都需要制作永久修改数据库。听起来你不允许这样做,而且我认为你没有太多可以在没有这种永久性改变的情况下做到这一点 - 并且当你与项目经理讨论时,称之为改进 - 到数据库。
答案 3 :(得分:2)
我假设当你说“最后一行”时,你的意思是“最后创建的行”。
即使你有主键,它仍然不是使用它的最佳选择确定行创建顺序。
无法保证在具有较小主键值的行之后创建具有较大主键值的行
即使主键位于标识列上,您仍然可以始终使用覆盖插入上的标识值
set identity_insert on
。
最好有时间戳列,例如带有默认约束的CreatedDateTime。
你会在这个字段上有索引。
那么你的查询将是简单,有效和正确的:
select top 1 *
from MyTable
order by CreatedDateTime desc
如果您没有时间戳列,则无法确定“最后一行”。
答案 4 :(得分:0)
如果您不允许编辑此表,您是否考虑过创建视图,或者复制表中的数据并将其移动到具有主键的数据中?
听起来很讨厌,但是,你的800k行表没有主键,所以hacky似乎是当天的顺序。 :)
答案 5 :(得分:0)
我相信您可以将其写为
SELECT * FROM table ORDER BY rowid DESC LIMIT 1;
希望有帮助。