数据库-sql-面试-rank

表名为 A:
ID SCORE
1 28
2 33
3 33
4 89
5 99
6 68
7 68
8 78
9 88
10 90
得到结果:
ID SCORE RANK
5 99 1
10 90 2
4 89 3
9 88 4
8 78 5
6 68 6
7 68 7
2 33 8
3 33 9
1 28 10
注意 select中是这样命名变量的 := 也可以set 用=

#使用变量方式
SELECT id,
       score,
       rank
  FROM (SELECT tmp.id,
               tmp.score,
               @rank := @rank + 1 AS rank
          FROM (SELECT id,score
                  FROM a
                 ORDER BY score desc) tmp, (SELECT @rank   := 0) a) RESULT;  
 desc user_order;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 REGION_ID                                          NUMBER(2)
 CUSTOMER_ID                                  NUMBER(2)
 CUSTOMER_SALES                          NUMBER
 select * from user_order order by customer_sales;

 REGION_ID CUSTOMER_ID CUSTOMER_SALES
---------- ----------- --------------
         5           1              151162
        10          29             903383
         6           7              971585
        10          28            986964
         9          21           1020541
         9          22           1036146
         8          16           1068467
         6           8            1141638
         5           3            1161286
         5           5            1169926
         8          19           1174421
         7          12           1182275
         7          11           1190421
         6          10           1196748
         6           9            1208959
        10          30          1216858
         5             2                1224992
           9             24              1224992
           9             23              1224992
           8          18           1253840
         7          15           1255591
         7          13           1310434
        10          27          1322747
         8          20           1413722
         6           6            1788836
        10          26          1808949
         5           4            1878275
         7          14           1929774
         8          17           1944281
         9          25           2232703
select rownum, t.*
     from (select *
              from user_order
            order by customer_sales desc) t
  where rownum <= 12
   order by customer_sales desc;

    ROWNUM  REGION_ID CUSTOMER_ID CUSTOMER_SALES
---------- ---------- ----------- --------------
         1          9                 25        2232703
         2          8                 17        1944281
         3          7                 14        1929774
         4          5                   4        1878275
         5         10                26        1808949
         6          6                   6        1788836
         7          8                 20        1413722
         8         10                27        1322747
         9          7                13        1310434
        10          7               15        1255591
        11          8               18        1253840
          12             5                     2          1224992

漏掉了另外两条记录
①ROW_NUMBER:
Row_number函数返回一个唯一的值,当碰到相同数据时,排名按照记录集中记录的顺序依次递增。
②DENSE_RANK:
Dense_rank函数返回一个唯一的值,除非当碰到相同数据时,此时所有相同数据的排名都是一样的。
③RANK:
Rank函数返回一个唯一的值,除非遇到相同的数据时,此时所有相同数据的排名是一样的,同时会在最后一条相同记录和下一条不同记录的排名之间空出排名。
使用Oracle函数

select region_id, customer_id, sum(customer_sales) total,
        rank() over(order by sum(customer_sales) desc) rank,
         dense_rank() over(order by sum(customer_sales) desc) dense_rank,
        row_number() over(order by sum(customer_sales) desc) row_number
     from user_order
    group by region_id, customer_id;

①假如客户就只需要指定数目的记录,那么采用row_number是最简单的,但有漏掉的记录的危险

②假如客户需要所有达到排名水平的记录,那么采用rank或dense_rank是不错的选择。至于选择哪一种则看客户的需要,选择dense_rank或得到最大的记录

上面的排名是按订单总额来进行排列的,现在跟进一步:假如是为各个地区的订单总额进行排名呢?这意味着又多了一次分组操作:对记录按地区分组然后进行排名。幸亏Oracle也提供了这样的支持,我们所要做的仅仅是在over函数中order by的前面增加一个分组子句:partition by region_id

select region_id, customer_id,
               sum(customer_sales) total,
         rank() over(partition by region_id
                        order by sum(customer_sales) desc) rank,
         dense_rank() over(partition by region_id
                        order by sum(customer_sales) desc) dense_rank,
         row_number() over(partition by region_id
                        order by sum(customer_sales) desc) row_number

    from user_order
   group by region_id, customer_id;

排名将是基于各个地区的,而非所有区域的了,Partition by 子句在排列函数中的作用是将一个结果集划分成几个部分,这样排列函数就能够应用于这各个子集。

时间: 2024-12-24 04:55:23

数据库-sql-面试-rank的相关文章

MySQL数据库SQL语句的C++ ODBC接口类测试结果 (转载)

c++|mysql|odbc|数据|数据库|语句 发信人: engineer (剑胆琴心~还是得走,sigh...), 信区: Linux 标  题: MySQL数据库SQL语句的C++ ODBC接口类测试结果 (转载) 发信站: BBS 水木清华站 (Mon Aug  9 18:03:47 1999)   [ 以下文字转载自 Database 讨论区 ] [ 原文由 engineer 所发表 ]         MySql数据库SQL语句的C++ ODBC接口类测试结果            

asp.NET上传文件到指定文件夹,ACCESS数据库,SQL数据库代码

access|asp.net|上传|数据|数据库 /* 我修改了一天时间.终于找到门路了.呵呵ACCESS中存放文件内容的字段类型为:OLE对象SQL中存放文件内容的字段类型为:image此代码为上传文件代码.梢后整理发布下载文件代码 代码设计实现功能:asp.NET上传文件到指定文件夹,ACCESS数据库,SQL数据库代码 已经测试文件格式 .TXT,JPG..MDB.GIF */ using System;using System.Collections;using System.Compo

菜鸟刚学html5,要通过什么方法才能在网页上显示表格,表格内容来自远程数据库sql

问题描述 菜鸟刚学html5,要通过什么方法才能在网页上显示表格,表格内容来自远程数据库sql 要在网页上显示表格内容,内容来自远程数据库sql,网页是asp.net 解决方案 asp.net不是有datalist,repater那种控件,你用repeater 的itemtemplate模板放tr,然后设置repeater数据源进行绑定就行了 解决方案二: 应该可以在前台用ajax获取 我个人之前试用过的方法是让后台生成接口,前台直接调用接口获取数据,并呈现出来. 解决方案三: 和html5没有

sql2005-eclipse对数据库sql server2005的增删改查

问题描述 eclipse对数据库sql server2005的增删改查 package Frame; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.sql.*; import java.awt.*; import javax.swing.*; public class data extends JFrame implements ActionListener{ //priv

oracl数据库sql语句怎么查询工资最低的两名员工编号,姓名,工资等信息。

问题描述 oracl数据库sql语句怎么查询工资最低的两名员工编号,姓名,工资等信息. 查询每个部门工资最低的两个员工编号,姓名,工资,等信息.关键是工资最低的两名员工 解决方案 SELECT * FROM ( SELECT bumen, price, ROW_NUMBER () OVER ( PARTITION BY bumen ORDER BY bumen, price DESC ) rn FROM table1 WHERE bumen IN ( SELECT bumen FROM tabl

textbox-求大神指导C#数据库SQL语句updatedata

问题描述 求大神指导C#数据库SQL语句updatedata String SQLString = string.Format(" update {0} set 坐标X/m= {1},坐标Y/m={2},高程H/m={3} where 点号='{4}'",str,int.Parse(textBox1.Text),int.Parse(textBox2.Text),int.Parse(textBox3.Text),textBox4.Text);///设置sql查询语句 OleDbDataA

oracle 数据库 sql 问题

问题描述 oracle 数据库 sql 问题 select pdept, deptsort, deptlevel, 省略 from (省略) t group by cube(pdept, deptsort, deptlevel) -- having grouping_id(pdept, deptsort, deptlevel) not in(2)------------------------A 1.问题是这样的 查询数据可能有 0 1 2 3 4 5 6 7 2.去掉 A处的注释,not in

c语言-C怎么连接到本地数据库sql server2008

问题描述 C怎么连接到本地数据库sql server2008 我想用C语言连接到local sql server 2008,并且对数据库进行读写操作. 解决方案 到网上查一下好喽,网上很多的. 解决方案二: 直接调C#写好的dll吧, 比较简单一点

sql-C# 按行读取txt文本内容导入数据库SQL(1)第二行数据就从第二列插入(2)索引超出了数组界限?

问题描述 C# 按行读取txt文本内容导入数据库SQL(1)第二行数据就从第二列插入(2)索引超出了数组界限? 都是按行读取txt内容,(因为有两行数据和其他的不一样)用正则分析出来,赋给一个字符串数组, 将一个字符串数组的每个值一次写入数据库行的对应列.一行读取完成. 可是却显示,索引超出了数组界限,数组个数和行对应的 .将读取出来的数据显示在textBox中是正确的, 但是奇怪的是也确实是导入进去了,数据库中表格有了数据 最终结果似乎对的,除了第二行第一列没有数据.谢谢,刚入手,第一个程序!

select-关于数据库sql拼写!急!!!!

问题描述 关于数据库sql拼写!急!!!! 从2015-01-01开始到2015-01-31,提取每天22点到第二天9点的数据,注意有开始时间(START_TIME)和结束时间(END_TIME) 我的sql: select A.BILLING,sum(out + in) from inf.EVEN_TGAS A where A.START_TIME between '2015-01-01 22:00:00' and '2015-01-31 09:00:00' and A.end_TIME be