Oracle 函数进阶、分组排序、列转行、cast 类型转换、dbms_random 生成随机数、sys_guid
目录
row_number() over 分组排序
rank() over 跳级分组排名
dense_rank() over() 连续分组排名
列转行 wm_concat
列转行 listagg() within group
cast 数据类型转换
dbms_random 生成随机数
生成随机数字
生成随机字符串
从表中获取随机数据
sys_guid() 生成 UUID
~~~ 准备员工表与部门表测试数据
row_number() over 分组排序
函数格式:row_number() over([partition by column1] order by column2)
1、根据 column1 分组,在分组内部根据 column2 排序,返回每组内部排序后的顺序编号(此行号组内连续且唯一)
2、不加 partition by column1 时,表示只排序不分组。
3、特别提醒:select 语句执行顺序:from ...> where ...> group by ...> having ... > select ...> order by ...
使用举例
--查询所有人员,工资由高到低排序,第一列(xh)是行号,从1开始且连续。 select row_number() over(order by t.sal desc) as xh , t.* from emp t ; |
|
--查询所有人员,部门内部员工的工资由高到低排序 select row_number() over(partition by t.deptno order by t.sal desc) as xh , t.* from emp t ; |
|
--查询每个部门中工资最高的人 (这里只是介绍用法,实际中可能存在工资一样的人,此时需要使用 dense_rank() over ) select t2.* from ( select row_number() over(partition by t.deptno order by t.sal desc) as xh , t.* from emp t ) t2 where t2.xh <=1; |
|
-- 使用 row_number() over 分组排序方式(只需要嵌套1层子查询) -- 使用 rownum 方式分页,查询员工数据,根据员工编号倒序排序(需要嵌套2层子查询) |
rank() over 跳级分组排名
dense_rank() over() 连续分组排名
1、rank() over、dense_rank() over(),用法和格式与 row_number() over 完全一样,区别如下:
--查询所有人员,按工资的由高到低排序,不支持并列排名
select row_number() over(order by t.sal desc) as xh , t.* from emp t ;
---查询所有人员,按工资的由高到低排序,支持并列排名,且排名不会跳级
select dense_rank() over(order by t.sal desc) as xh , t.* from emp t ;
---查询所有人员,按工资的由高到低排序,支持并列排名,但是排名会跳级
select rank() over(order by t.sal desc) as xh , t.* from emp t ;
列转行 wm_concat
1、wm_concat 函数平时在 PL/SQL 或者命令行中使用还是挺方便的,但是不推荐写在程序代码中,Oracle 官方更推荐使用下面的 listagg() within group 函数。
2、wm_concat 函数
-- 1、查询员工表中的所有员工姓名,并转为一行,用 "," 隔开,如: 张三,李四,Jock select wm_concat(ename) as names from emp t; |
|
-- 2、按部门编号分组查看每个部门中的员工姓名 select deptno,wm_concat(ename) as names from emp group by deptno; |
|
-- 3、通过Oracle 系统视图查询 emp 表的所有字段,如:EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO --这个操作还是非常有用的,比如一个表有几十个或者上百个字段,select x,y,z ...,如果靠人工一个个写,太累而且容易出错 |
列转行 listagg() within group
1、Oracle 官方更推荐使用 listagg 函数,格式:listagg(column_nname,delimiter) [within group (order by order_by_column)];
column_nname:待转换的列名,如 ename delimiter:分隔符,默认为 null,无分隔符 order_by_column:指定列值拼接顺序,如 order by ename listagg 是必须的,排序的 within group 是可选的! |
2、listagg 函数使用举例如下:
--查询所有员工的姓名,用 "+" 号分割,如:SMITH+张三+WARD+JONES+MARTIN+李四+MILLER select listagg(t.ename,'+') as names from emp t ; |
--分组查看各部门的员工姓名,使用 "," 分割,姓名按薪水高低排列拼接 select t.deptno,listagg(t.ename,',') within group(order by t.sal desc) as neames from emp t group by t.deptno; |
--查询指定表的所有字段,对于想要快速获取某个表的字段是非常有用的操作 select listagg(t.COLUMN_NAME,',') within group(order by t.COLUMN_ID) from user_tab_columns t where t.TABLE_NAME = 'EMP'; |
cast 数据类型转换
1、cast() 函数用于转换数据类型,格式:cast(列名/值 as 目标数据类型),值为 null 时不会有影响。
2、使用举例如下:
select cast('124' as number) + 100 as total from dual; -- 字符串转数值,输出 224 |
select concat(cast(t.sal as varchar2(32)),'00') as str from emp t; --数值转字符串,sal 值为 null 时,不会有影响。 |
--浮点型精度截断:emp.sal 原本类型是 number(7,2) ,转换之后为 number(18,0) 表示小数位数为 0,结果就是对 sal 字段的值取整,且四舍五入,如 2850.55 -> 2851 select cast(t.sal as number(18,0)) as str from emp t; |
select cast(t.sal as number(18,4)) as str from emp t; --浮点型精度截断:同理也可以增加精度,如:2850.55 -> 2850.5500 |
dbms_random 生成随机数
Oracle 官网 dbms_random 文档:DBMS_RANDOM
生成随机数字
dbms_random.random 用于生成正负整数 |
select dbms_random.random as random from dual; -- 生成一个10位数的正负随机数,如 -765136417、1703191771 |
-- 生成一个10位数的正随机数,使用绝对值函数辅助,如 228821755、1542114642 select abs(dbms_random.random) as random from dual; |
select abs(mod(dbms_random.random,100)) as random from dual; -- 生成一个 100 以内的随机正数,使用取余函数+绝对值函数辅助 |
select 100 + abs(mod(dbms_random.random,999)) as random from dual; -- 生成一个 100—999 的随机整数 |
dbms_random.value 用于生成随机小数 |
select dbms_random.value as random from dual; -- 生成一个 0~1 之间随机小数,精确到小数点后面 15 位,如 0.623657615937181 |
-- 生成一个 10—100 之间的随机小数,精确到小数点后面 15 位,如 14.2489446249136 select dbms_random.value(10,100) as random from dual; |
-- 生成一个 10—999 之间的随机小数,精确到小数点后面 2 位,如 6538.26 select round(dbms_random.value(10,9999),2) as random from dual; |
-- 生成一个100~1000之间的随机整数,使用 trunc 小数截断函数赋值,强行去掉小数位 select trunc(100 + 900 * dbms_random.value, 0) as random from dual; |
-- 生成一个[10,100)之间的随机整数 select trunc(dbms_random.value(10,100)) as random from dual; |
-- 生成一个由数字组成的 16 位的随机字符串,使用 cast 函数辅助,以 '.' 开头,如:.980565525834441。(注意最长也只能是 39 位) select cast(dbms_random.value as varchar2(16)) from dual; |
-- 生成一个由数字组成的 32 位的随机字符串,使用 substr、cast 函数辅助,如:74899075116317540687814596072324 select substr(cast(dbms_random.value as varchar2(39)),2,32) as random from dual ; |
生成随机字符串
格式:dbms_random.string(opt, length) opt 可取值:'u' 或者 'U' :大写字母、'l' 或者 'L' : 小写字母、'a' 或者 'A' : 大小写字母、'x' 或者 'X' : 数字与大写字母、'p' 或者 'P' : 可打印字符。 length:生成的字符串长度 |
select dbms_random.string('x',20) from dual; -- 生成如: BRFSJLU79P909RLZ7FJI select dbms_random.string('P',20) from dual; -- 生成如: E}"-!GS{w,/H?PT$}y&l |
select sys_guid() from dual; --生成 32 位的 guid 随机字符串,如:AE2AE001C4BC4C259CBC8CFF443E5801
从表中获取随机数据
select * from emp order by dbms_random.random; --查询所有员工,并随机排序输出 |
--从员工表中随机或取 4 个员工数据 select * from ( select * from emp order by dbms_random.random) where rownum < 5; |
sys_guid() 生成 UUID
1、Java JDK 有 API 可以生成 UUID,Oracle 中也有相应的方法可以生成 —— sys_guid(),可以很方便的防止主键冲突。
2、正常的 UUID 是 36 位的(包括其中的4个"-"),而 sys_guid() 生成的不带 "-",默认是 32 位。
select sys_guid() from dual; -- 生成 32 位的 GUID,大写字母+数字,如:9B654FEF9D1D43BDB05406699049CA26 |
|
-- 随机生成 100 个UUID declare total number := 100; begin dbms_output.put_line('========随机生成' || total ||' 个UUID值========'); for i in 1..total loop dbms_output.put_line(i || '===>' || sys_guid()); end loop; end; |
|
create table STUDENT2 ( stuid VARCHAR2(38) not null, stuname VARCHAR2(10) not null ); insert into STUDENT2(stuid,stuname) values(sys_guid(),'张三');-- 插入数据,stuid 使用 GUID 随机生成 insert into STUDENT2(stuid,stuname) values(dbms_random.string('x',20),'老四');-- 使用20位的随机字符串作为 stuid 的值 |
Oracle 函数进阶、分组排序、列转行、cast 类型转换、dbms_random 生成随机数、sys_guid相关推荐
- oracle --高级函数应用-pivot (列转行)
系列文章目录 oracle --高级函数应用-pivot使用 文章目录 系列文章目录 一.pivot 作用? 二.使用步骤 1.创建表 2.插入数据 3.查询结果 总结 提示:以下是本篇文章正文内容, ...
- 【Oracle】开窗函数、分组排序 row_number\partition by 详解
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.row_number是什么? 二.partition by是什么? 三.加上条件筛选你想要的记录 前言 提示:这里 ...
- oracle和mysql分组排序取第一条数据
场景 需求 查每个人的Orderstr 是1 的数据,并保证name不重复 oracle select * from (SELECT a.*, row_number() over(partitio ...
- oracle系列–行转列、列转行
oracle行转列.oracle列转行 以及 mysql列转行,mysql行转列 文章目录 前言 一.oracle:逗号分隔的一列转行 二.oracle:多列转行 unpivot 函数 三.oracl ...
- Sql进阶用法(分组排序|级联删除)
开窗函数,分组排序 rank() over(partition by [field] order by [field] [asc/desc]) --同排名不连续 1 1 3 row_number() ...
- Spark 列转行操作
前言 在MySQL和oracle中有列转行函数用于将列转成行.在大数据SQL中也有类似的操作.这里主要讲解Spark的列转行操作. 欢迎关注微信公众号:大数据报文 concat:多列合并 在介绍列转行 ...
- mysql列转行、行转列
1.列转行 SELECT product_id, 'store1' store, store1 price FROM products WHERE store1 IS NOT NULL UNION S ...
- sqlservice 列转行
实际工作中的一些操作 大家好,我是你们的好朋友程序员:铭文 一.列转行 二.行转列 大家好,我是你们的好朋友程序员:铭文 先简单的说下:今天的工作要写一个列转行的操作,好久没写这个方法了.不 太熟悉了 ...
- SQL 行转列 列转行 Oracle转置函数函数pivot、unpivot 解决wm_concat 没有排序
https://www.cnblogs.com/mellowsmile/p/4642306.html HH 终风且暴,顾我则笑,谑浪笑敖,中心是悼. 终风且霾,惠然肯来,莫往莫来,悠悠我思. 博客园 ...
- oracle数据列转行排序,oracle 列转行函数 WMSYS.WM_CONCAT 排序不规则处理
业务中做报表,需要将一列列数据汇总成一行,然后汇总,如下: 需要将每个产品进行汇总,通过ichartjs进行展示,图表中需要数据的顺序是: var data = [ { name : '产品1', v ...
最新文章
- GPU上的基本线性代数
- 后香农时代,华为提出10大数学挑战问题
- ubuntu 命令收集
- SQL Server 跨库同步数据
- Bootstrap Glyphicons图标
- 【数据结构】——构建二叉树,遍历二叉树
- mac下解决中文乱码的问题
- python发音翻译-Python translate()方法
- 一、1.1 Kaggle中kernel技巧
- Yii2中Component和Object的使用方法
- 打印工资条怎么做到每个人都有表头明细_一键批量生成工资条并群发,操作步骤详解...
- 如何将图片转换成PCBLogo
- Android 如何获取运行内存和总运行内存等
- 旧唐书 卷一百九十六下 列传第一百四十六下
- 麦麦题全网独家最全题库每日更新数据
- Android 获取手机联系人代码
- Kotlin学习——了解Kotlin
- 如何构建营销活动平台(一):前言概述
- 来聊聊云计算能否彻底改变业务和软件架构
- 学习英语单词16个 - day1
热门文章
- Windows下PHP安装配置
- java jvm 1.6_JVM1.6 GC详解
- 拓端tecdat|MATLAB用深度学习长短期记忆 (LSTM) 神经网络对智能手机传感器时间序列数据进行分类
- 高数基础 第七章 无穷级数
- mysql二进制包安装mysql_基于linux使用mysql二进制包安装mysql
- Python parser中的nargs
- python无法显示饼图
- 燃情动作——《速度与激情:特别行动》影评数据分析可视化
- 3分钟了解计算机基础知识,你对电脑还一无所知?3分钟带你全面了解电脑基础知识...
- python中文相似度_python比较两个文本的相似性