根据订单排名前两位的结果

时间:2014-03-08 15:08:36

标签: sql sql-server group-by row-number

我一直试图让这个与一些row_number,group by,top,类似的东西一起工作,但我错过了一些基本的概念。我有一张这样的桌子:

+-------+-------+-------+
| name  |  ord  |  f_id |
+-------+-------+-------+
| a     |   1   |   2   |
| b     |   5   |   2   |
| c     |   6   |   2   |
| d     |   2   |   1   |
| e     |   4   |   1   |
| a     |   2   |   3   |
| c     |  50   |   4   |
+-------+-------+-------+

我想要的输出是:

+-------+---------+--------+-------+
| f_id  |  ord_n  |  ord   |  name |
+-------+---------+--------+-------+
| 2     |   1     |   1    |  a    |
| 2     |   2     |   5    |  b    |
| 1     |   1     |   2    |  d    |
| 1     |   2     |   4    |  e    |
| 3     |   1     |   2    |  a    |
| 4     |   1     |   50   |  c    |
+-------+---------+--------+-------+

数据按ord值排序,每个f_id最多只能输出两个结果。我应该为此处理存储过程还是我可以使用SQL执行此操作?我已经尝试了一些精选的TOP子查询,但没有任何东西可以接近......

以下是创建测试表的一些陈述:

create table help(name varchar(255),ord tinyint,f_id tinyint);
insert into help values
('a',1,2),
('b',5,2),
('c',6,2),
('d',2,1),
('e',4,1),
('a',2,3),
('c',50,4);

1 个答案:

答案 0 :(得分:3)

您可以使用Rank or DENSE_RANK个功能。

select A.name, A.ord_n, A.ord , A.f_id  from 
  (
    select 
    RANK() OVER (partition by f_id ORDER BY ord asc) AS "Rank", 
    ROW_NUMBER() OVER (partition by f_id ORDER BY ord asc) AS "ord_n", 
    help.*
    from help
  ) A where A.rank <= 2

Sqlfiddle demo