tags:

views:

84

answers:

9

Hi, I have a table and I need retrieve the ID of the First and Second row. How to achieve that ? By Top 2 I select two first rows, but I need only second row

+1  A: 

You can use select top 2 Id from yourtable.

swapneel
+1  A: 
SELECT TOP 2 [Id] FROM table
Simon
You can order your results, so top will return not first two added but whether first and second you need
Simon
YOu must order the results, you have no guarantees you wil get the first two added without an order by. Never use a top without an order by and expect to get the earliest records added.
HLGEM
+1  A: 

Use "TOP 2" in the select to get the desired number of rows in output. This would return in the sequence the data was created. If you have a date option you could order by the date along with TOP n Clause.

To get the top 2 rows; SELECT TOP 2 [Id] FROM table

To get the top 2 rows order by some field SELECT TOP 2[ID] FROM table ORDER BY ASC/DESC

To Get only 2nd Row;

WITH Resulttable AS ( SELECT TOP 2 *, ROW_NUMBER() OVER(ORDER BY YourColumn) AS RowNumber FROM @Table )
SELECT * FROM Resultstable WHERE RowNumber=2

Dheer
+1  A: 

Select top 2 [id] from table Order by [id] desc should give you want you the latest two rows added.

However, you will have to pay particular attention to the order by clause as that will determine the 1st and 2nd row returned.

If the query was to be changed like this:

Select top 2 [id] from table Order by ModifiedDate desc

You could get two different rows. You will have to decide which column to use in your order by statement.

Barry
+4  A: 

Assuming SQL Server 2005+ an example of how to get just the second row (which I think you may be asking - and is the reason why top won't work for you?)

set statistics io on

;with cte as
(
select * ,
ROW_NUMBER() over (order by number) as rn
from master.dbo.spt_values
) 
select * from cte where rn=2

/*Just to add in what I was running RE: Comments*/
;with cte as
(
select top 2 * ,
ROW_NUMBER() over (order by number) as rn
from master.dbo.spt_values
) 
select * from cte where rn=2
Martin Smith
by using `TOP 2` in the CTE, like I do in my answer (inaddition to the `ROW_NUMBER()`), you can improve the efficiency of the query by a factor of about 6. Using `set showplan_all on` my version has a TotalSubtreeCost of 0.0125678 while this version (without using a `TOP 2`) has a value of 0.06937763, while returning the same result set.
KM
@KM - I'm not sure whether there is a real saving there as opposed to helping make the estimated cost more accurate. When I use `set statistics io on` it doesn't look as though it makes any difference. I'm quite wary of reading too much into the figures given in the execution plan ever since this http://stackoverflow.com/questions/3424650/sql-query-pervious-row-optimisation/3426364#3426364
Martin Smith
when I run it with `set statistics io on`, your version runs with `Table 'spt_values'. Scan count 1, logical reads 18, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.` after adding the `TOP 2`, I get `Table 'spt_values'. Scan count 1, logical reads 6, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.` Also, the `set showplan_all on` shows that the execution plans are different.
KM
@KM - Are you running the same as the code in my edited answer? I've tested on SQL Server 2008 and 2005 and on both got `Table 'spt_values'. Scan count 1, logical reads 6, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.` Maybe a service pack dependant behaviour then?
Martin Smith
Yes, I'm running it just like in your edit, 1st version has: `Table 'spt_values'. Scan count 1, logical reads 18, physical reads 1, read-ahead reads 16, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.` and the 2nd version (with TOP 2) has: `Table 'spt_values'. Scan count 1, logical reads 6, physical reads 2, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.`. when I run `select count(*) from master.dbo.spt_values` I get `2346`, what do you get? if you have the same number of rows, it might come down to hardware and memory usage.
KM
@KM - I get `2346` on SQL Server 2005 and `2506` on SQL Server 2008. I already +1 ed your answer I guess that would indeed be the safer option then.
Martin Smith
when I run this on tables other than `master.dbo.spt_values`, I see similar results (fewer logical and/or physical reads) when using the `TOP 2`
KM
+1  A: 

Certainly TOP will surfice if you simply want the TOP 2, but if you need them individually so that you can do something with those values then use the ROW_NUMBER which will give you more control over the rows you want to select

ps. I did this as i'm not sure if the OP is after a simple TOP 2 in a select. (I may be wrong!)

-- Get first row, same as TOP 1
SELECT [Id] FROM 
(
    SELECT [Id], ROW_NUMBER() OVER (ORDER BY [Id]) AS Rownumber
    FROM table
) results
WHERE results.Rownumber = 1

-- Get second row only
SELECT [Id] FROM 
(
    SELECT [Id], ROW_NUMBER() OVER (ORDER BY [Id]) AS Rownumber
    FROM table
) results
WHERE results.Rownumber = 2
kevchadders
+1  A: 

I'm guessing you're using SQL 2005 or greater. The 2nd line selects the top 2 rows by using 'ORDER BY ROW_COUNT DESC". Since I used "DESC", the 2nd row is arranged as being first.

SELECT TOP 1 COLUMN1, COLUMN2 from (
SELECT TOP 2 COLUMN1, COLUMN2 FROM Table ORDER BY ROW_NUMBER DESC )
+1  A: 
with T1 as
(
select row_number() over(order by ID) rownum, T2.ID
from Table2 T2
)
select ID from T1 where rownum=2
Anil
+2  A: 

Use ROW_NUMBER() to number the rows, but use TOP to only process the first two.

try this:

DECLARE @YourTable table (YourColumn int)
INSERT @YourTable VALUES (5)
INSERT @YourTable VALUES (7)
INSERT @YourTable VALUES (9)
INSERT @YourTable VALUES (17)
INSERT @YourTable VALUES (25)

;WITH YourCTE AS
(
SELECT TOP 2
    *, ROW_NUMBER() OVER(ORDER BY YourColumn) AS RowNumber
    FROM @YourTable
) 
SELECT * FROM YourCTE WHERE RowNumber=2

OUTPUT:

YourColumn  RowNumber
----------- --------------------
7           2

(1 row(s) affected)
KM