Oracle 中关于NUMBER的一些规则

Oracle NUMBER类型详解
本文深入解析Oracle数据库中NUMBER数据类型的使用规则,包括精度(precision)和刻度(scale)的概念,以及它们如何影响数字的存储和处理。当整数部分长度超过p-s时,Oracle将报错;小数部分长度超过scale时,会进行四舍五入。

NUMBER(precision, scale)

定点数的精度§和刻度(s)遵循以下规则:

  1. 当一个数的整数部分的长度 > p-s 时,Oracle就会报错

  2. 当一个数的小数部分的长度 > s 时,Oracle就会舍入。

  3. 当s(scale)为负数时,Oracle就对小数点左边的s个数字进行舍入。

  4. 当s > p 时, p表示小数点后第s位向左最多可以有多少位数字,如果大于p则Oracle报错,小数点后s位向右的数字被舍入

原博文链接
https://www.cnblogs.com/oumyye/p/4448656.html

<think>嗯,用户想了解Oracle数据库中ROW_NUMBER函数的用法和示例。首先,我需要回忆一下这个函数的基本语法和常见应用场景。根据引用[1],ROW_NUMBER()是一个窗口函数,用于给结果集的每一行分配唯一的序号。语法结构是ROW_NUMBER() OVER ([PARTITION BY column] ORDER BY column),其中PARTITION BY是可选的,用于分组,ORDER BY决定排序方式。 接下来,用户可能需要具体的示例来理解如何应用。比如,基本用法应该是按照某个字段排序后添加序号,比如按薪资排序。然后,分组的例子,比如按部门分组后排序。还有去重或取每组的第一条数据,这时候结合子查询,筛选rn=1的情况。 需要注意用户可能的应用场景,比如分页查询或者数据去重,这时候要给出相应的示例。例如,分页查询可以使用ROW_NUMBER配合WHERE子句来限制行数,但更常见的是用OFFSET-FETCH,不过ROW_NUMBER也是一种方法。数据去重方面,比如同一个部门可能有重复记录,取最新或最高的一条,这时候用PARTITION BY部门,ORDER BY时间或薪资降序,再选rn=1。 还要提醒用户注意性能问题,尤其是在处理大数据量时,合理的索引和分区可以提高效率。同时,与RANK和DENSE_RANK的区别可能需要解释,但用户的问题没有提到,所以可能放在相关问题里。 检查引用内容,确保示例正确。引用[3]中的示例是Hive的,但Oracle类似,所以可以调整成Oracle的语法。例如,子查询中使用ROW_NUMBER,然后外层筛选rn=1。需要确保语法正确,比如OVER子句的正确使用,别名rn的应用。 用户可能的问题还包括如何在实际开发中使用,比如在存储过程或复杂查询中的应用,但根据引用[2],用户提到ROW_NUMBER在复杂业务需求中很有用,可以举一个稍微复杂的例子,比如分页查询结合排序和分组。 最后,生成相关问题时要考虑用户可能的后续疑问,比如性能优化、与其他函数的对比、常见错误等。确保问题覆盖用户可能的需求,帮助他们深入理解。</think>### Oracle ROW_NUMBER函数详解及示例 #### 1. 函数定义与语法 ROW_NUMBER()是Oracle数据库中的窗口函数,为查询结果集的每一行分配**唯一递增的整数序号**,序号从1开始。其基本语法为: ```sql ROW_NUMBER() OVER ( [PARTITION BY 分组字段] ORDER BY 排序字段 [ASC|DESC] ) AS 别名 ``` #### 2. 核心参数解析 - **PARTITION BY**(可选) 将数据按指定字段分组,每组内单独计算行号。例如按部门分组时,每个部门会重新从1开始编号。 - **ORDER BY**(必选) 决定组内数据的排序规则,直接影响行号的生成顺序。例如按薪资降序排列时,行号1表示组内最高薪资。 #### 3. 典型应用场景与示例 ##### 场景1:基础排序编号 ```sql SELECT employee_id, salary, ROW_NUMBER() OVER (ORDER BY salary DESC) AS rn FROM employees; ``` 结果示例: ``` EMPLOYEE_ID | SALARY | RN ----------------------------- 101 | 25000 | 1 102 | 22000 | 2 103 | 20000 | 3 ``` ##### 场景2:分组排名(如部门薪资排名) ```sql SELECT department_id, employee_id, salary, ROW_NUMBER() OVER ( PARTITION BY department_id ORDER BY salary DESC ) AS dept_rank FROM employees; ``` 结果示例: ``` DEPARTMENT_ID | EMPLOYEE_ID | SALARY | DEPT_RANK ------------------------------------------------ 10 | 101 | 25000 | 1 10 | 104 | 18000 | 2 20 | 105 | 30000 | 1 ``` ##### 场景3:数据去重(取每组最新记录) ```sql SELECT * FROM ( SELECT product_id, update_time, ROW_NUMBER() OVER ( PARTITION BY product_id ORDER BY update_time DESC ) AS rn FROM product_versions ) WHERE rn = 1; ``` 通过子查询筛选`rn=1`,可获取每个产品的最新版本记录[^3]。 ##### 场景4:分页查询 ```sql SELECT * FROM ( SELECT t.*, ROW_NUMBER() OVER (ORDER BY create_time DESC) AS rn FROM orders t ) WHERE rn BETWEEN 11 AND 20; ``` 该写法常用于实现每页10条数据的第二页查询。 #### 4. 注意事项 - **唯一性保证**:即使排序字段值相同,ROW_NUMBER()仍会生成不同序号(与RANK()函数不同)[^1] - **性能优化**:建议对`PARTITION BY`和`ORDER BY`涉及的字段建立索引 - **执行顺序**:窗口函数在WHERE、GROUP BY之后执行,但可在SELECT子句中直接使用
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值