选择group by子句中的前n行

时间:2009-06-16 21:37:25

标签: sql sql-server

我的架构类似于以下内容:

create table bar
(
    instrument varchar(255) not null,
    bar_dttm datetime not null,
    bar_open int not null,
    bar_close int not null
)

我想查询该表,并返回每个工具最近的5行。

我可以通过仪器仪表,用:

select top 5 instrument, bar_dttm, bar_open, bar_close
from bar
where instrument = 'XXX'
order by bar_dttm desc

我想在一次查询中同时为所有乐器执行此操作。这可能吗?我正在运行SQL Server 2008。

3 个答案:

答案 0 :(得分:12)

CROSS APPLY就是你通常这样做的方式 - http://msdn.microsoft.com/en-us/library/ms175156.aspx

编辑 - 添加示例,如下所示:

select
    bar1.instrument
    ,bar2.*
from (
    select distinct instrument from bar) as bar1
cross apply (
    select top 5
        bar2.instrument
        ,bar2.bar_dttm
        ,bar2.bar_open
        ,bar2.bar_close 
    from bar as bar2 where bar2.instrument = bar1.instrument) as bar2

通常,您希望在此处添加订单。

编辑 - 为查询添加了不同的内容,希望这可以让您想要。 修改 - 在顶部添加了缺少的“select”关键字。副本&粘贴bug FTL!

答案 1 :(得分:7)

使用SQL 2008,您可以使用带有CTE的分区行号子句...

with MyCte AS (SELECT      instrument, 
                           bar_dttm, 
                           bar_open, 
                           bar_close,
                           PartitionedRowNum = ROW_NUMBER() OVER (PARTITION BY instrument ORDER BY bar_dttm DESC)
               from        bar)
select  *
from    MyCte
where   PartitionedRowNum <= 5

答案 2 :(得分:3)

也可以使用Row_Number - http://msdn.microsoft.com/en-us/library/ms186734.aspx

WITH foo as (
Select
 *
 ,ROW_NUMBER() OVER(PARTITION BY instrument ORDER BY bar_dttm desc) as rank
from
 bar
)

select 
 *
from
 foo
where
 rank <= 5