2017-07-28 45 views
1

我试图让每个组组合中的第n行,例如前n行

用下面的输入我想获得每个产品区相结合的前两排,有序按日期:

product area date  units 
A  US 2015/08/07 10 
A  US 2015/08/08 12 
A  US 2015/08/09 15 
A  UK 2015/08/07 13 
A  UK 2015/08/10 11 
B  US 2015/08/07 16 
B  US 2015/08/08 17 
B  US 2015/08/09 12 
B  UK 2015/08/07 10 
B  UK 2015/08/08 09 
B  UK 2015/08/09 07 

将返回

product area date  units 
A  US 2015/08/07 10 
A  US 2015/08/08 12 
A  UK 2015/08/07 13 
A  UK 2015/08/10 11 
B  US 2015/08/07 16 
B  US 2015/08/08 17 
B  UK 2015/08/07 10 
B  UK 2015/08/08 09 

我已经试过:

with ordered as (select product, area, date, units, 
          row_number() over (partition by product, area order by date asc) as date_rank 
          from mytable) 
          select product, area, date, units 
          from ordered 
          where date_rank <= 2 
+3

你的查询有什么问题?你的问题是什么? –

回答

1

查询返回正确的结果。我看到,可以从您的查询中唯一缺少的是对你最后的selectorder by

with ordered as (
    select product, area, date, units 
    , row_number() over (partition by product, area order by date asc) as date_rank 
    from mytable 
) 
select product, area, date, units 
from ordered 
where date_rank <= 2 
order by product, area desc, date_rank 

rextester演示:http://rextester.com/XOMS68876

回报:

+---------+------+------------+-------+ 
| product | area | date | units | 
+---------+------+------------+-------+ 
| A  | us | 2015-08-07 | 10 | 
| A  | us | 2015-08-08 | 12 | 
| A  | uk | 2015-08-07 | 13 | 
| A  | uk | 2015-08-10 | 11 | 
| B  | us | 2015-08-07 | 16 | 
| B  | us | 2015-08-08 | 17 | 
| B  | uk | 2015-08-07 | 10 | 
| B  | uk | 2015-08-08 |  9 | 
+---------+------+------------+-------+ 
1

尝试CROSS APPLY

SELECT t1.product, t1.area, t2.date, t2.units 
FROM (
    SELECT DISTINCT t1.product, t1.area 
    FROM mytable 
) AS t1 
CROSS APPLY (
    SELECT TOP 2 date, units 
    FROM mytable t2 
    WHERE t1.product = t2.product and t1.area = t2.area 
    ORDER BY date DESC 
) AS t2 
1

您可以使用ROW_NUMBER ()

SELECT Product, Area, Date, Units 
    FROM (SELECT *, ROW_NUMBER() OVER (PARTITION BY product, area ORDER By date ASC) AS xRowNumber FROM MyTable) xyz 
     WHERE xRowNumber < 3