您的位置:首页 > 数据库 > SQL

SQL Server 分组取 Top 笔记(row_number + over 实现)

2015-07-06 10:56 651 查看
先看SQL语句(注意:这是在SQL Server 2005+ [包括2005] 的版本才支持的哦,o(∩_∩)o 哈哈~)

SELECT

  col1,col2,col3

FROM table1 AS a WITH(NOLOCK) INNER JOIN(

  // 第一部分代码

  SELECT

    b1.col1,b1.col2,b1.col3,

    ROW_NUMBER() OVER ( PARTITION BY b1.分组列名 ORDER BY b1.排序列 DESC/ASC ) AS sortedId

  FROM table1 AS b1 WITH(NOLOCK)

) AS b WITH(NOLOCK) ON a.id=b.id

WHERE b.sortedId>= 需要 获取的 top 值

----------------------------------------------------------------------------------------------------------------------------------

// 第一部分代码(为什么这样写?)

重点是记录一下自己对 ROW_NUMBER() OVER ( ...... ) 组合的理解。

记得有一次面试,遇到这样一个问题( 怎么获取一张表 第30-40的数据记录,注意:表的主键id,可能不连续)。

大牛看到后,肯定会喷我的,那么简单,你说个毛啊。

是的,您喷得对,确实很很简单嘛。

SELECT

  id,col1,col2

FROM table1 a INNER JOIN (

  SELECT

    id,

    ROW_NUMBER() OVER ( ORDER BY ID ASC ) as rowId

  FROM table1 b1

) AS b ON a.id = b.id

WHERE b.rowId BETWEEN $strartId AND $endId

------------------------------------------------------------------------------------------------------------------------

好吧,言归正传

ROW_NUMBER() OVER ( [ PARTITION BY 分组列名 ] ORDER BY 排序列 DESC/ASC ) AS sortedId

ROW_NUMBER() 为每一行数据分配一个连续的编号,这个编号可以一样的哦,它取决于后面的 OVER( [表达式] ORDER BY xxx DESC/ASC )

PARTITION BY col1 :通过 OVER 告诉 ROW_NUMBER() ,如果 2行(或者更多行) col1值是一样的,你就给我一样的编号,不要分配新的编号给我,谢谢~~ o(∩_∩)o

也就是说 用 【 ROW_NUMBER() OVER ( [ PARTITION BY col1] ORDER BY 排序列 DESC/ASC ) AS sortedId】生成的sortedId 实际上是按照 col1 分组了的

好嘛,扯完了,举个栗子呗。加深自己的印象。

有一张学生考试成绩表 stuSorceInfo(统计每一科成绩的第一名 [ 前三名,前N ])

主键ID    学生ID      科目ID      分数

id      studentId    subjectId    score

1 1         1         81

-------------------------------------------------------------

2 1         2        88

-------------------------------------------------------------

3 2         1         80

-------------------------------------------------------------

4 2         2         98

-------------------------------------------------------------

获取 每一科成绩的第一名

SELECT a.* FROM stuSorceInfo a WHERE INNER JOIN (

  SELECT

    b1.studentId,

    ROW_NUMBER( PARTTION BY subjectId ORDER BY b1.socre DESC ) sortedId

  FROM stuSorceInfo b1

) AS b ON a.id=b.id WHERE b.sortedId=1 (第一名:=1,前三名:<=3 ,前N名:<=N)

参考资料:
http://blog.csdn.net/wuzhengqing1/article/details/8024634 http://www.cnblogs.com/gy51Testing/archive/2012/07/26/2609832.html
感谢每一位blog朋友的分享,谢谢!o(∩_∩)o 哈
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: