简体   繁体   中英

SQL query for obtaining top 10 rows for each different value of a column

I have a table that is defined as follows:

The first column denotes the date, the second denotes a 'futures contract' called 'term description'(TDF) and the third is the Price for the TDF.

   Date          TDF     Price
2012-01-30      Jan-12   32.75
2012-01-30      Feb-12   45.21
2012-01-30      Mar-12   37.34
2012-01-31      Jan-12   33.57
2012-01-31      Feb-12   34.80
2012-01-31      Feb-12   38.56
2012-02-01      Jan-12   47.97
2012-02-01      Feb-12   43.13
2012-02-01      Mar-12   38.41
2012-02-01      Apr-12   38.56

I have the above result set from a query. From this I need to get the first 2 rows for each date. That is 2 for 30th Jan, 2 for 31st JAN, 2 for 1st Feb. How do i go about this?

select TermDescription,ContractDate,Price,SortOrder into #tbtp from BaseTermPrice 
inner hash join Term 
on 
Term.TermID = BaseTermPrice.TermID
where BaseID = 19 and PeakType = 'On-Pk'
and ContractDate > '2011-01-01'
order by ContractDate,SortOrder

The above query yielded the table I have posted above. Then I thought the following query would yield me the desired result:

select top 2 ContractDate,TermDescription,Price from #tbtp a WHERE 
a.ContractDate in (Select distinct(ContractDate) from #tbtp)

but it did not. It just yielded the top 2 rows of the table posted above. Not 2 rows for each date as I want. Please help.

Assuming you have a temporary table called #tbtp holding the data shown, you can try this to get the desired results:

;with cte as 
(select 
 [Date], 
 TDF,
 Price, 
 row_number() over (partition by [Date] order by [Date], TDF) rn
 from #tbtp)
 select [Date], TDF, Price
 from cte
 where rn in (1,2)

What happens here is this: We first partition the table into subsets, where the key for a subset is the Date column. Then we order the rows by Date and TDF within each subset. The row_number() functions assigns a sequence number to each row based on the above operations. Finally, we just use the row number to filter and get the desired rows. If we wanted the first n rows, we could have used the filter where rn < (n+1) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM