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


    先看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 哈

  • 相关阅读:
    行列式运算法则
    神经元的数学模型
    Neural Network and Artificial Neural Network
    常见的23种设计模式
    Java 基本数据类型 及 == 与 equals 方法的区别
    MySQL经典编程问题
    MyEclipse配置tomcat报错
    MySQL 日期类型函数及使用
    MySQL dump文件导入
    MySQL 的两个特殊属性 unsigned与 zerofill
  • 原文地址:https://www.cnblogs.com/oceanho/p/4623778.html
Copyright © 2020-2023  润新知