Oracle数据库rownum和row_number的不同点

yizhihongxing

Oracle数据库rownum和row_number的不同点

在Oracle数据库中,我们常常会用到rownumrow_number这两个关键字来操作行数据。它们虽然都可以用来对查询结果的行数进行限制,但它们有着不同的用法和功效。本文将详细讲解这两个关键字的区别,并结合实例进行说明。

rownum

rownum是Oracle数据库中内置的一个伪列,它在查询结果返回之后才会计算。rownum可以用来计算查询结果集中每一行的行号,但不能在where字句中使用和修改,因为它是在计算结果后才产生的。一般情况下,rownum的使用如下:

select * from table where rownum <= 10;

此语句的作用是查询table表中前10行数据。

示例1

我们假设有一个表employee,其中包含员工信息,例如姓名、年龄、性别等:

id name age gender
1 Alice 25 Female
2 Bob 28 Male
3 Chris 30 Male
4 David 35 Male
5 Emily 23 Female
6 Frank 31 Male
7 Grace 27 Female
8 Helen 29 Female
9 Ida 24 Female
10 Jack 33 Male
11 Kevin 26 Male
12 Lucy 32 Female
13 Mary 28 Female
14 Nancy 25 Female
15 Olivia 29 Female
16 Peter 30 Male
17 Queenie 27 Female
18 Rose 31 Female
19 Steve 28 Male
20 Tom 32 Male

我们希望查询employee表中前5条年龄最小的员工信息,可以使用如下查询语句:

select * from (
  select * from employee order by age
) where rownum <= 5;

这个查询语句中,先通过子查询将employee表按年龄从小到大排序,然后再对查询结果使用rownum进行限制,只返回前5行。

结果如下:

id name age gender
5 Emily 23 Female
9 Ida 24 Female
1 Alice 25 Female
14 Nancy 25 Female
7 Grace 27 Female

示例2

我们继续使用上面的employee表,假设现在有一个需求:查询年龄在25岁以上的前5个员工信息。如果直接使用rownum限制行数,会得到以下结果:

select * from employee where age >= 25 and rownum <= 5;

结果:

id name age gender
1 Alice 25 Female

我们发现这个查询语句只返回了一行记录,不符合我们的要求。这是因为查询条件age >= 25rownum <= 5在执行查询时是同时进行的,Oracle数据库返回了满足条件的第一行即结束。为了避免这种情况的发生,我们可以使用以下方式:

select * from (
  select * from employee where age >= 25 order by age
) where rownum <= 5;

在这个查询语句中,我们先对年龄大于等于25岁的员工进行筛选,然后按年龄从小到大排序,最后对结果使用rownum进行限制。这样就可以得到正确的结果了。

row_number

row_number是Oracle数据库中窗口函数中的一种,它可以用来计算查询结果集中每一行的行号。与rownum不同的是,row_number是在查询结果返回之前产生的,因此可以进行更为灵活的操作。一般情况下,row_number的使用如下:

select row_number() over (order by column_name) as row_num, *
from table;

此语句的作用是为查询结果集中的每一行添加一个序列号row_num,使其按指定列名进行排序。

示例1

我们仍然使用上面的employee表作为例子,现在需求变成了查询年龄在25岁以上的前5个员工信息,但是我们需要同时显示它们在所有员工中的排名。

select row_number() over (order by age) as row_num, e.*
from employee e
where age >= 25 and rownum <= 5;

这个查询语句中使用了row_number函数,并使用age来进行排序,同时仍然对结果集进行rownum限制。得到的结果如下:

row_num id name age gender
1 1 Alice 25 Female
2 14 Nancy 25 Female
3 7 Grace 27 Female
4 18 Rose 31 Female
5 12 Lucy 32 Female

我们可以看到,查询结果中不仅包含了员工信息,还将查询结果集中的每一行按年龄从小到大排序,并添加了一个序列号row_num,使得我们可以轻松得到每个员工在所有员工中的排名。

示例2

假设我们现在有一个需求:查询男性员工信息,并按年龄从小到大排序,在每个年龄段内按工资从高到低排序,最后给工资最高的男性员工输出"赚钱特别多"。我们可以使用如下SQL语句:

select 
  id, name, age, salary,
  rank() over (partition by age order by salary desc) as salary_rank
from employee
where gender = 'Male'
order by age, salary desc;

这个查询语句在查询结果中使用rank()函数,对员工按年龄分组,然后按工资从高到低进行排序,并添加一个salary_rank列,用来表示该员工在同龄男性员工中的收入排名。最后还对查询结果按年龄从小到大,再按工资从高到低进行排序。

为了输出"赚钱特别多"的男性员工,我们还需要在以上SQL语句的基础上进行扩展,可以看下面的SQL语句:

with male_salary_rank as (
  select 
    id, name, age, salary, 
    rank() over (partition by age order by salary desc) as salary_rank
  from employee
  where gender = 'Male'
)
select 
  id, name, age, salary, 
  case
    when age in (25, 30) and salary_rank = 1 then '赚钱特别多'
    else ''
  end as comment
from male_salary_rank
order by age, salary desc;

这个SQL语句先使用公共表达式将查询结果存放到male_salary_rank中,然后对male_salary_rank中的内容进行加工,使用case语句对年龄为25岁和30岁的员工进行特别处理,输出"赚钱特别多"的信息。最后再将结果按年龄从小到大,再按工资从高到低进行排序。

总结

rownumrow_number都可以用来计算查询结果集中每一行的行号,但它们有着不同的用法和功效。rownum是Oracle数据库中内置的一个伪列,它在查询结果返回之后才会计算;row_number是Oracle数据库中窗口函数中的一种,它可以用来计算查询结果集中每一行的行号,同时可以进行更为灵活的操作。可以根据具体需求,灵活选择使用这两个关键字来操作行数据。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Oracle数据库rownum和row_number的不同点 - Python技术站

(0)
上一篇 2023年5月21日
下一篇 2023年5月21日

相关文章

  • CentOS系统下MongoDB安装及配置教程

    以下是CentOS系统下MongoDB安装及配置教程的完整攻略: 1. 安装 MongoDB 在 CentOS 系统中,可以使用 yum 命令来安装 MongoDB。具体操作步骤如下: 使用 root 用户登录 CentOS 系统。 执行以下命令安装 MongoDB: sudo yum install mongodb-server 安装完成后,启动 Mong…

    database 2023年5月22日
    00
  • Windows安装Redis并添加本地自启动服务的实例详解

    Windows安装Redis并添加本地自启动服务的实例详解 概述 Redis 是开源的内存数据结构存储系统。在一些需要频繁读写数据库的应用中,使用 Redis 持久化数据可以提高读写速度和性能,同时降低数据库的压力。 本篇教程将详细介绍在 Windows 平台上如何安装 Redis,并添加本地自启动服务。 准备条件 下载 Redis 安装包 从 Redis …

    database 2023年5月22日
    00
  • APMServ使用说明

    APMServ使用说明 1. 安装APMServ APMServ是一个Windows下的PHP集成环境,可以自动安装Apache、PHP、MySQL、phpMyAdmin等服务,方便快速搭建本地开发环境。 前往官网http://www.apmset.com/下载最新版本的APMServ,根据安装步骤完成安装。 2. 启动APMServ服务 安装完成后,启动A…

    database 2023年5月19日
    00
  • Spring Boot 项目集成Redis的方式详解

    下面是Spring Boot 整合Redis的完整攻略: 准备工作 在开始配置之前,我们需要完成几个基本的准备工作。 添加Redis依赖 使用Spring Boot集成Redis需要在pom.xml中添加spring-boot-starter-data-redis依赖,建议使用最新版本。 <dependency> <groupId>o…

    database 2023年5月22日
    00
  • thinkphp项目部署到Linux服务器上报错“模板不存在”如何解决

    当在 Linux 服务器上部署 ThinkPHP 项目时,如果出现“模板不存在”的错误提示信息,通常会有以下两种情况: 模板文件路径错误 模板文件缓存导致的路径错误 针对这两种情况,我们可以采取以下措施解决: 模板文件路径错误 如果是因为模板文件路径错误导致的问题,通常可以查看以下两个文件: ThinkPHP/Conf/convention.php:该文件是…

    database 2023年5月18日
    00
  • SQL查询字段被包含语句

    SQL查询字段被包含语句,通常是用于查找包含指定关键词的数据行。下面是详细的攻略: 1. 理解SQL查询字段被包含语句 SQL查询语句中,使用 LIKE 运算符进行模糊匹配。比如,我们要查找包含关键词 “apple” 的数据行,可以使用以下查询语句: SELECT * FROM table_name WHERE column_name LIKE ‘%appl…

    database 2023年5月21日
    00
  • Sql学习第三天——SQL 关于CTE(公用表达式)的递归查询使用

    让我来详细讲解一下关于 SQL 中 CTE(公用表达式)的递归查询使用。 什么是 CTE CTE,全称 Common Table Expression,是用于创建可被其他查询引用的临时结果集的方法,它是一种类似于子查询的结构,但可以被选择、更新、删除或者插入等其他查询复用。 递归查询 递归查询是指在一张表当中进行自我引用的查询操作,用于在具有父子关系的数据中…

    database 2023年5月21日
    00
  • 通过Navicat for MySQL远程连接的时候报错mysql 1130的解决方法

    这是一篇关于“通过Navicat for MySQL远程连接的时候报错mysql 1130的解决方法”的攻略,攻略包含以下内容: 问题原因 解决方法 配置允许远程连接的账户和密码 配置服务器的防火墙规则 示例说明 问题原因 当我们在使用Navicat for MySQL远程连接MySQL数据库时,会遇到以下错误: error 1130 (HY000): Ho…

    database 2023年5月18日
    00
合作推广
合作推广
分享本页
返回顶部