每组组合前n行

时间:2017-07-28 11:29:22

标签: sql sql-server

我试图为每个组合获得前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 个答案:

答案 0 :(得分: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 :(得分:1)

您的查询返回正确的结果。对于您的最终order by,我在查询中唯一可能遗漏的内容是select

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 |
+---------+------+------------+-------+

答案 2 :(得分: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