zoukankan      html  css  js  c++  java
  • 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 哈

  • 相关阅读:
    解决Maven项目 Missing artifact jdk.tools:jdk.tools:1.7的错误
    Hive三种不同的数据导出的方式
    【万字总结】图解堆算法、链表、栈与队列(多图预警)
    精心收集的Hadoop学习资料(持续更新)
    [大牛翻译系列]Hadoop 翻译文章索引
    sql server代理服务无法启动(SQL Agent):OpenSQLServerInstanceRegKey:GetRegKeyAccessMask failed (reason: 2).
    【转】sql server迁移到mysql
    linux shell中的EOF
    yum源出问题,rpmdb: BDB0113 Thread/process 17276/140338032428864 failed: BDB1507 Thread died in Berkeley DB library
    linux网卡出现问题:Job for network.service failed because the control process exited with error code问题
  • 原文地址:https://www.cnblogs.com/oceanho/p/4623778.html
Copyright © 2011-2022 走看看