views:

3647

answers:

10

I want to select the last 5 records from a table in SQL Server without arranging the table in ascending or descending order.

+3  A: 

Without an order, this is impossible. What defines the "bottom"? The following will select 5 rows according to how they are stored in the database.

SELECT TOP 5 * FROM [TableName]

Stefan Mai
Right, also you can add an "order by colx desc" to bottom 5 depending on the indexes. ie. the top 5 *ARE* the bottom 5 if you reverse the order.
Booji Boy
A: 

You can retrieve them from memory.
So first you get the rows in a DataSet, and then get the last 5 out of the DataSet.

Dr. Hfuhruhurr
umm, ya, I don't think that's what he meant dude. +1 since you are a noob and didn't mean to post a dumb answer.
Booji Boy
+3  A: 

This is just about the most bizarre query I've ever written, but I'm pretty sure it gets the "last 5" rows from a table without ordering:

select * 
from issues
where issueid not in (
    select top (
        (select count(*) from issues) - 5
    ) issueid
    from issues
)

Note that this makes use of SQL Server 2005's ability to pass a value into the "top" clause - it doesn't work on SQL Server 2000.

Matt Hamilton
If by last, you mean in the order of the clustered key, then I'm afarid that does not work
Mitch Wheat
I tested this on a table that doesn't have a clustered index, and it returned the last five rows that I get when doing a simple "select * from issues".
Matt Hamilton
And just tried it on a table with an "identity int" primary key, and it worked there too. Got me the "last five" rows.
Matt Hamilton
OK. I tested on a table with clustered index.
Mitch Wheat
without order by this doesn't work. period. you might come into a situation when one query piggy backs on the results of another query and the results can be tottaly different.
Mladen Prajdic
+1  A: 

Well, the "last five rows" are actually the last five rows depending on your clustered index. Your clustered index, by definition, is the way that he rows are ordered. So you really can't get the "last five rows" without some order. You can, however, get the last five rows as it pertains to the clustered index.

SELECT TOP 5 * FROM MyTable
ORDER BY MyCLusteredIndexColumn1, MyCLusteredIndexColumnq, ..., MyCLusteredIndexColumnN DESC
Charles Graham
A: 

There is a handy trick that works in some databases for ordering in database order,

SELECT * FROM TableName ORDER BY true

Apparently, this can work in conjunction with any of the other suggestions posted here to leave the results in "order they came out of the database" order, which in some databases, is the order they were last modified in.

Kent Fredric
+1  A: 

The way your question is phrased makes it sound like you think you have to physically resort the data in the table in order to get it back in the order you want. If so, this is not the case, the ORDER BY clause exists for this purpose. The physical order in which the records are stored remains unchanged when using ORDER BY. The records are sorted in memory (or in temporary disk space) before they are returned.

Note that the order that records get returned is not guaranteed without using an ORDER BY clause. So, while any of the the suggestions here may work, there is no reason to think they will continue to work, nor can you prove that they work in all cases with your current database. This is by design - I am assuming it is to give the database engine the freedom do as it will with the records in order to obtain best performance in the case where there is no explicit order specified.

Assuming you wanted the last 5 records sorted by the field Name in ascending order, you could do something like this, which should work in either SQL 2000 or 2005:

select Name 
from (
    select top 5 Name 
    from MyTable 
    order by Name desc
) a 
order by Name asc
RedFilter
+1  A: 

If you know how many rows there will be in total you can use the ROW_NUMBER() function. Here's an examble from MSDN (http://msdn.microsoft.com/en-us/library/ms186734.aspx)

USE AdventureWorks;
GO
WITH OrderedOrders AS
(
    SELECT SalesOrderID, OrderDate,
    ROW_NUMBER() OVER (ORDER BY OrderDate) AS 'RowNumber'
    FROM Sales.SalesOrderHeader 
) 
SELECT * 
FROM OrderedOrders 
WHERE RowNumber BETWEEN 50 AND 60;
idstam
+1  A: 

Suppose you have an index on id, this will be lightning fast:

SELECT * FROM [MyTable] WHERE [id] > (SELECT MAX([id]) - 5 FROM [MyTable])
msuvajac
A: 

select * from table order by empno(primary key) desc fetch first 5 rows only

Shrabani Joarder
As written, selects all rows in descending order, not just first 5.
JYelton
A: 
  1. You need to count number of rows inside table ( say we have 12 rows )
  2. then subtract 5 rows from them ( we are now in 7 )
  3. select * where index_column > 7

select * from users where user_id > ( (select COUNT(*) from users) - 5)

you can order they ASC or DESC

But when using this code

select TOP 5 from users order by user_id DESC

it will not be order easily

M.M.F