Taking the second last row with only one select in SQL Server?
The best way to do this (and compatible with the ANSI SQL standard), is to use a CTE (Common Table Expression) with the ROW_NUMBER
function:
;WITH OrderedCinemas AS
(
SELECT
CinemaID, CinemaName,
ROW_NUMBER() OVER(ORDER BY CinemaID DESC) AS 'RowNum'
FROM dbo.Cinema
)
SELECT
CinemaID, CinemaName
FROM OrderedCinemas
WHERE RowNum = 2
By using this construction, you can get the second highest value very easily - or the fifth hightest (WHERE RowNum = 5
) or the top 3 rows (WHERE RowNum <= 3
) or whatever you need - the CinemaID
values are just ordered and sequentially numbered for your use.
To get the 2nd last row in one select:
SELECT TOP 1 * From
(select Top 2 * from Cinema ORDER BY CinemaID DESC) x
ORDER BY CinemaID
It's really only "one" select because the outer select is over only 2 rows.
The following doesn't work, explaination of why: Using ranking-function derived column in where clause (SQL Server 2008)
I'll keep it here for completeness:
SELECT row_number() OVER (ORDER BY col) r, *
FROM tbl
WHERE r = 2
More info: http://www.bidn.com/blogs/marcoadf/bidn-blog/379/ranking-functions-row_number-vs-rank-vs-dense_rank-vs-ntile
So I think the most readable way of doing it is:
SELECT * FROM (SELECT row_number() OVER (ORDER BY col) r, * FROM tbl) q
WHERE r = 2