前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Oracle列转行函数 Listagg() 语法详解及应用实例「建议收藏」

Oracle列转行函数 Listagg() 语法详解及应用实例「建议收藏」

作者头像
全栈程序员站长
发布于 2022-10-03 02:26:15
发布于 2022-10-03 02:26:15
18K00
代码可运行
举报
运行总次数:0
代码可运行

大家好,又见面了,我是你们的朋友全栈君。

工作中用到一段比较复杂的SQL查询脚本,使用了listagg()函数实现了具有多个值的字段的填充(即,列表聚合,list aggregation(我猜的))。

说简单点,listagg()函数可以实现多列记录聚合为一条记录,从而实现数据的压缩、致密化(data densification)。

以下内容转载自http://dacoolbaby.iteye.com/blog/1698957,SQL脚本做了部分优化,增加了输出结果。

————————————————————————-

这是一个Oracle的列转行函数:LISTAGG()

先看示例代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
with temp as(  
select 'China' nation ,'Guangzhou' city from dual union all  
select 'China' nation ,'Shanghai' city from dual union all  
select 'China' nation ,'Beijing' city from dual union all  
select 'USA' nation ,'New York' city from dual union all  
select 'USA' nation ,'Bostom' city from dual union all  
select 'Japan' nation ,'Tokyo' city from dual   
)  
select nation,listagg(city,',') within GROUP (order by city)  as Cities
from temp  
group by nation

运行结果:

这是最基础的用法:

LISTAGG(XXX,XXX) WITHIN GROUP( ORDER BY XXX),

用法就像聚合函数一样,通过Group by语句,把每个Group的一个字段,拼接起来,非常方便。

同样是聚合函数,还有一个高级用法:

就是over(partition by XXX)

也就是说,在你不使用Group by语句时候,也可以使用LISTAGG函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
with temp as(  
select 500 population, 'China' nation ,'Guangzhou' city from dual union all  
select 1500 population, 'China' nation ,'Shanghai' city from dual union all  
select 500 population, 'China' nation ,'Beijing' city from dual union all  
select 1000 population, 'USA' nation ,'New York' city from dual union all  
select 500 population, 'USA' nation ,'Bostom' city from dual union all  
select 500 population, 'Japan' nation ,'Tokyo' city from dual   
)  
select population,  
nation,  
city,  
listagg(city,',') within GROUP (order by city) over (partition by nation) rank  
from temp

运行结果:

总结:LISTAGG()把它当作SUM()函数来使用就可以了。

Oracle Database SQL Language Reference上有关listagg()函数的描述如下:

—————————————————————————————————————————–

Purpose For a specified measure, LISTAGG orders data within each group specified in the ORDER BY clause and then concatenates the values of the measure column. ■ As a single-set aggregate function, LISTAGG operates on all rows and returns a single output row. ■ As a group-set aggregate, the function operates on and returns an output row for each group defined by the GROUP BY clause. ■ As an analytic function, LISTAGG partitions the query result set into groups based on one or more expression in the query_partition_clause. The arguments to the function are subject to the following rules: ■ The measure_expr can be any expression. Null values in the measure column are ignored. ■ The delimiter_expr designates the string that is to separate the measure values. This clause is optional and defaults to NULL. ■ The order_by_clause determines the order in which the concatenated values are returned. The function is deterministic only if the ORDER BY column list achieved unique ordering. The return data type is RAW if the measure column is RAW; otherwise the return value is VARCHAR2. Aggregate Examples The following single-set aggregate example lists all of the employees in Department 30 in the hr.employees table, ordered by hire date and last name: SELECT LISTAGG(last_name, ‘; ‘) WITHIN GROUP (ORDER BY hire_date, last_name) “Emp_list”, MIN(hire_date) “Earliest” FROM employees WHERE department_id = 30; Emp_list Earliest ———————————————————— ——— Raphaely; Khoo; Tobias; Baida; Himuro; Colmenares 07-DEC-02 The following group-set aggregate example lists, for each department ID in the hr.employees table, the employees in that department in order of their hire date:

SELECT department_id “Dept.”, LISTAGG(last_name, ‘; ‘) WITHIN GROUP (ORDER BY hire_date) “Employees” FROM employees GROUP BY department_id ORDER BY department_id; Dept. Employees —— ———————————————————— 10 Whalen 20 Hartstein; Fay 30 Raphaely; Khoo; Tobias; Baida; Himuro; Colmenares 40 Mavris 50 Kaufling; Ladwig; Rajs; Sarchand; Bell; Mallin; Weiss; Davie s; Marlow; Bull; Everett; Fripp; Chung; Nayer; Dilly; Bissot ; Vollman; Stiles; Atkinson; Taylor; Seo; Fleaur; Matos; Pat el; Walsh; Feeney; Dellinger; McCain; Vargas; Gates; Rogers; Mikkilineni; Landry; Cabrio; Jones; Olson; OConnell; Sulliv an; Mourgos; Gee; Perkins; Grant; Geoni; Philtanker; Markle 60 Austin; Hunold; Pataballa; Lorentz; Ernst 70 Baer . . . Analytic Example The following analytic example shows, for each employee hired earlier than September 1, 2003, the employee’s department, hire date, and all other employees in that department also hired before September 1, 2003: SELECT department_id “Dept”, hire_date “Date”, last_name “Name”, LISTAGG(last_name, ‘; ‘) WITHIN GROUP (ORDER BY hire_date, last_name) OVER (PARTITION BY department_id) as “Emp_list” FROM employees WHERE hire_date < ’01-SEP-2003′ ORDER BY “Dept”, “Date”, “Name”; Dept Date Name Emp_list —– ——— ————— ——————————————— 30 07-DEC-02 Raphaely Raphaely; Khoo 30 18-MAY-03 Khoo Raphaely; Khoo 40 07-JUN-02 Mavris Mavris 50 01-MAY-03 Kaufling Kaufling; Ladwig 50 14-JUL-03 Ladwig Kaufling; Ladwig 70 07-JUN-02 Baer Baer 90 13-JAN-01 De Haan De Haan; King 90 17-JUN-03 King De Haan; King 100 16-AUG-02 Faviet Faviet; Greenberg 100 17-AUG-02 Greenberg Faviet; Greenberg 110 07-JUN-02 Gietz Gietz; Higgins 110 07-JUN-02 Higgins Gietz; Higgins

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/197718.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年9月3日 下,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Oracle学习笔记:oracle+110个常用函数
1. ASCII 返回与指定的字符对应的十进制数; SQL> select ascii(A) A,ascii(a) a,ascii(0) zero,ascii( ) space from dual; A A ZERO SPACE --------- --------- --------- --------- 65 97 48 32 2. CHR 给出整数,返回对应的字符; SQL> select chr(54740) zhao,chr(65) chr65 from dual; ZH C -- - 赵 A 3. CONCAT 连接两个字符串; SQL> select concat(010-,88888888)||转23 高乾竞电话from dual; 高乾竞电话 ---------------- 010-88888888转23 4. INITCAP 返回字符串并将字符串的第一个字母变为大写; SQL> select initcap(smith) upp from dual; UPP ----- Smith 5.INSTR(C1,C2,I,J) 在一个字符串中搜索指定的字符,返回发现指定的字符的位置; C1 被搜索的字符串 C2 希望搜索的字符串 I 搜索的开始位置,默认为1 J 出现的位置,默认为1 SQL> select instr(oracle traning,ra,1,2) instring from dual; INSTRING --------- 9 6.LENGTH 返回字符串的长度; SQL> select name,length(name),addr,length(addr),sal,length(to_char(sal))from gao.nchar_tst; NAME LENGTH(NAME) ADDR LENGTH(ADDR) SAL LENGTH(TO_CHAR(SAL)) ------ ------------ ---------------- ------------ ----------------------------- 高乾竞 3 北京市海锭区 69999.99 7 7.LOWER 返回字符串,并将所有的字符小写 SQL> select lower(AaBbCcDd)AaBbCcDd from dual; AABBCCDD -------- aabbccdd 8.UPPER 返回字符串,并将所有的字符大写 SQL> select upper(AaBbCcDd) upper from dual; UPPER -------- AABBCCDD 9.RPAD和LPAD(粘贴字符) RPAD 在列的右边粘贴字符 LPAD 在列的左边粘贴字符 SQL> select lpad(rpad(gao,10,*),17,*)from dual; LPAD(RPAD(GAO,1 ----------------- *******gao******* 不够字符则用*来填满 10.LTRIM和RTRIM LTRIM 删除左边出现的字符串 RTRIM 删除右边出现的字符串 SQL> select ltrim(rtrim( gao qian jing , ), ) from dual; LTRIM(RTRIM( ------------- gao qian jing 11.SUBSTR(string,start,count) 取子字符串,从start开始,取count个 SQL> select substr(13088888888,3,8) from dual; SUBSTR( -------- 08888888 12.REPLACE(string,s1,s2) string 希望被替换的字符或变量 s1 被替换的字符串 s2 要替换的字符串 SQL> select replace(he love you,he,i) from dual; REPLACE(H ---------- i love you 13.SOUNDEX[g1] 返回一个与给定的字符串读音相同的字符串 SQL> create table table1(xm varchar(8)); SQL> insert into table1 values(weather); SQL> insert into table1 values(wether); SQL> insert into table1 values(gao); SQL> select xm from table1 where soundex(xm)=soundex(weather); XM -------
用户1289394
2021/02/05
5310
listagg函数替代方案_listagg within group用法
这是一个Oracle的列转行函数:LISTAGG() 注:oracle 11.2才能用
全栈程序员站长
2022/10/04
1.7K0
listagg within group函数的作用_oracletochar函数
前言:最近在写一些比较复杂的SQL,是一些统计分析类的,动不动就三四百行,也是首次写那么长的SQL,有用到一些奇形怪状的SQL函数,在这里结合网上的例子做一些笔记,以后用到不记得用法可以翻出来看!
全栈程序员站长
2022/10/04
1.3K0
listagg within group函数的作用_oracletochar函数
Oracle学习笔记_05_分组函数
group by 增强:rollup      cube     grouping      grouping set
shirayner
2018/08/10
1.3K0
Oracle学习笔记_05_分组函数
Oracle分析函数三——SUM,AVG,MIN,MAX,COUNT
功能描述:对一组内发生的事情进行累积计数,如果指定*或一些非空常数,count将对所有行计数,如果指定一个表达式,count返回表达式非空赋值的计数,当有相同值出现时,这些相等的值都会被纳入被计算的值;可以使用DISTINCT来记录去掉一组中完全相同的数据后出现的行数。
python与大数据分析
2022/03/11
6430
Oracle分析函数三——SUM,AVG,MIN,MAX,COUNT
oracle数据库的sql语句练习1
//2. 打印公司里所有的manager_id select manager_id from employees
全栈程序员站长
2022/08/27
7420
MySql基础之面试查询语句
Java微观世界
2025/01/21
470
进阶数据库系列(十):PostgreSQL 视图与触发器
视图(View)本质上是一个存储在数据库中的查询语句。视图本身不包含数据,也被称为虚拟表。 我们在创建视图时给它指定了一个名称,然后可以像表一样对其进行查询。
民工哥
2023/08/22
1.4K0
进阶数据库系列(十):PostgreSQL 视图与触发器
Oracle分析函数五——统计分析函数
样本中各数据与样本平均数的差的平方和的平均数叫做样本方差;样本方差的算术平方根叫做样本标准差。样本方差和样本标准差都是衡量一个样本波动大小的量,样本方差或样本标准差越大,样本数据的波动就越大。
python与大数据分析
2022/03/11
9240
Oracle分析函数五——统计分析函数
Oracle迁移MySQL 8特殊SQL处理 顶
我们创建一个表,并生成两个表分区CUS_PART1,CUS_PART2.关于分区的分类可以参考https://www.cnblogs.com/wnlja/p/3979684.html
算法之名
2020/05/18
1.2K0
Oracle迁移MySQL 8特殊SQL处理
                                                                            顶
SQL学习日记(二)
例如:按照 department_id 查询 employees(员工表)和 departments(部门表)的信息。
量子态的沐子呓
2019/12/25
3720
Oracle分析函数四——函数RANK,DENSE_RANK,FIRST,LAST…
功能描述:根据ORDER BY子句中表达式的值,从查询返回的每一行,计算它们与其它行的相对位置。组内的数据按ORDER BY子句排序,然后给每一行赋一个号,从而形成一个序列,该序列从1开始,往后累加。每次ORDER BY表达式的值发生变化时,该序列也随之增加。有同样值的行得到同样的数字序号(认为null时相等的)。然而,如果两行的确得到同样的排序,则序数将随后跳跃。若两行序数为1,则没有序数2,序列将给组中的下一行分配值3,DENSE_RANK则没有任何跳跃。
python与大数据分析
2022/03/11
1.1K0
Oracle分析函数四——函数RANK,DENSE_RANK,FIRST,LAST…
Oracle实践|内置函数之聚合函数
Oracle 数据库提供了丰富的内置函数,涵盖数值处理、字符串操作、日期和时间处理、逻辑判断、集合处理、数据分析、数据类型转换等多个方面。上一个章节学习了数学类的函数,本章节想学习下分析类函数。下面就随着我一起来学习下这个内置函数吧,有解释不到之处,还望批评指正。
六月暴雪飞梨花
2024/06/13
3470
Oracle实践|内置函数之聚合函数
学习python第三天单行函数
解答:会出现问题(报错了),出错原因,因为在执行代码的过程中对于employee_id,last_name这两列都有107条数据, 而department_id去重之后只有12条数据,数量对不上了!所以报错了!总结:使用distinct需谨慎... 2.单行函数: 概念:单数据进单结果出(单进单出) 分类学习: 1).字符函数 2).数字函数 3).日期函数 4).转换函数 5).通用函数 字符函数: 1).大小写转换函数:3个 ①.lower(m):将字符串中所有字符转换为全小写 ②.upper(m):将字符串中所有字符转换为全大写 ③.initcap(m):将字符串中首字母转为大写,其余字母转换小写 代码实现:
hankleo
2020/09/16
6650
学习python第三天之多行函数
多行函数:(聚合函数/分组函数) 解释:多条数据进入,单条结果出来(多进单出) 1).max(obj):最大值 2).min(obj):最小值 3).sum(num):求和 4).avg(num):求平均值 5).count(obj):计数 【注意事项】: 1).max()和min()两个函数可以接受任何数据类型的实际参数 2).sum()和avg()两个函数只能接受number类型的数据 3).多行函数/聚合函数/分组函数满足自动忽略空值的特点(在某些情况下,我们不应该忽略空值...) 案例如下: 查询公司薪资最高的、最低的、工资总和以及平均值的信息? select max(salary),min(salary),sum(salary),avg(salary) from employees; 参看如下代码并思考: select max(last_name),max(hire_date),min(last_name),min(hire_date) from employees; 关于count()的使用: 需求如下: 查询公司有多少员工? select count(employee_id),count(last_name),count(hire_date) from employees; select count(1),count(2),count(0),count(107),count('*') from employees; 执行以上代码发现效果都是正确的,我们以后做计数操作的时候,我们都用count('*')来实现; 查看如下代码: select count(department_id),count(commission_pct) from employees; 执行以上代码发现问题所在,只要是多行函数/聚合函数/分组函数满足自动忽略空值的特点 修改以上代码实现需要的效果: select count(nvl(department_id,100)),count(nvl(commission_pct,1)) from employees; 思考:avg() = sum() / count()? 答:以上的等式成立 需求如下: 查询公司的平均奖金率? select avg(commission_pct),sum(commission_pct) / count(commission_pct), sum(commission_pct) / count(nvl(commission_pct,2)), sum(commission_pct) / 107, sum(commission_pct) / count(*) from employees; 作业: --1.显示系统时间(注:日期+时间) select to_char(sysdate,'yyyy/mm/dd hh24:mi:ss') from dual; --2.查询员工号,姓名,工资,以及工资提高百分之20%后的结果(new salary) select employee_id,last_name,salary,salary * 1.2 "new salary" from employees; --3.将员工的姓名按首字母排序,并写出姓名的长度(length) select last_name,length(last_name) from employees order by last_name; --4.查询各员工的姓名,并显示出各员工在公司工作的月份数(worked_month)。 select last_name,round(months_between(sysdate,hire_date),0) "worked_month" from employees; --5.查询员工的姓名,以及在公司工作的月份数(worked_month),并按月份数降序排列 select last_name,round(months_between(sysdate,hire_date),0) "worked_month" from employees order by "worked_month" desc; --方式一: select last_name || ' earns $' || salary || ' monthly but wants $' || 3 * salary "Dream Salary" from employees; --方式二: select last_name || ' earns' || to_char(salary,'$99999') || ' monthly but wants' || to_char(3 * salary,'$99999') "
hankleo
2020/09/16
4860
Oracle学习笔记_03_单行函数
单行函数:        操作数据对象        接受参数返回一个结果 只对一行进行变换  每行返回一个结果        可以转换数据类型        可以嵌套        参数可以是一列或一个值
shirayner
2018/08/10
6020
Oracle学习笔记_03_单行函数
MySQL排序与分页详解
第一个 “位置偏移量” 参数指示MySQL从哪一行开始显示,是一个可选参数,如果不指定“位置偏移量”,将会从表中的第一条记录开始(第一条记录的位置偏移量是0,第二条记录的位置偏移量是1,以此类推);
timerring
2023/02/17
2.1K0
MySQL排序与分页详解
Oracle分析函数二——函数用法
Oracle分析函数实际上操作对象是查询出的数据集,也就是说不需二次查询数据库,实际上就是oracle实现了一些我们自身需要编码实现的统计功能,对于简化开发工作量有很大的帮助,特别在开发第三方报表软件时是非常有帮助的。Oracle从8.1.6开始提供分析函数。
python与大数据分析
2022/03/11
5550
Oracle分析函数二——函数用法
最强总结!SQL Server/MySQL/Oracle函数完全指南!!
今天给大家总结的是SQL Server/MySQL/Oracle这三个关系数据库的函数内容,包含常用和不常用的。
SQL数据库开发
2024/11/13
3330
最强总结!SQL Server/MySQL/Oracle函数完全指南!!
学习python第三天数据库day2
day01回顾: 数据库: 定义:存储数据的仓库(database,简称db) 常用的数据库对象有哪些? 1).数据表(table) ***** 2).视图(view) 3).索引(index) 4).序列(sequence) 主流的关系型数据库有哪些?(枚举) oracle、mysql、sqlserver、db2... 谈一谈oracle和mysql的区别? oracle: 1).收费的(贵) 2).数据的存储量大,安全性高、效率比较快 mysql: 1).免费 2).数据的存储量小(相对而言的),安全系数以及效率方面较低(相对而言的) sql:structure query language(结构化查询语言) 分类: DDL:结构层面的操作,自动提交,无法回滚 比较强硬 包括的常用的操作如下: 建表、删表、修改表、清空表 --> 总结:结构发生变化了,都是ddl操作 建表的格式: create table 表名( 列名1 数据类型(长度), 列名2 数据类型(长度), ... 列名n 数据类型(长度) ); 建完表格之后我们可以使用desc关键字去查看表结构, desc关键字的使用如下: desc 表名; DML:数据层面的操作:不会自动提交,可以回滚比较柔和 包括的常用的操作如下: 增加数据(insert into ...) 删除数据(delete from 表名 where ...) 修改数据(update 表名 set 列名1 = 值1,列名2 = 值2,... where ...) 查询数据(select ... from 表名) 总结: 对于删除和修改数据而言,一般情况下都需要配合where子句进行相应的操作,否则会出现全删或者全改的问题!! DCL: 两个关键字:commit(提交)、rollback(回滚) day02(上午): 出题思考如何实现? 1).查询公司员工的编号,姓名,薪资,奖金率以及月收入? 以下代码有问题:因为有null值参与了算数运算,导致结果直接为null了,出现了与现实不符的情况!! select employee_id,last_name,salary,commission_pct,salary + salary * commission_pct from employees; 使用去空置换函数:nvl(m,n): 执行过程如下: 如果m得到的内容不为null,那么就拿它本身参与运算 如果m得到的内容为null,那么就用n的值参与运算 重构以上代码: select employee_id,last_name,salary,commission_pct,salary + salary * nvl(commission_pct,0) from employees; sql中的别名: 概念:使用别名的思想,可以让显示变得更加的优雅、简洁!并且可以优化我们的代码... 起别名有三种方式: 方式一: select employee_id,last_name,salary,commission_pct,salary + salary * nvl(commission_pct,0) as month_sal from employees; 方式二: select employee_id,last_name,salary,commission_pct,salary + salary * nvl(commission_pct,0) month_sal from employees; 方式三: select employee_id,last_name,salary,commission_pct,salary + salary * nvl(commission_pct,0) "month_sal" from employees; 比较理解以上的三种方式: 方式二可以认为是方式一的简化版,它们定义的别名在查询显示的时候,都是以全大写来进行显示 如果想要控制显示的大小写(效果),我们可以使用方式三来完成;我们可以认为方式三才是最实用的方式 where子句: 在查询数据的时候,很多情况下我们需要过滤掉一些不需要的内容,所以需要用到where子句来实现 记住: where紧随from 运算符: 分类: 1).比较运算符: 范围: >大于 >=大于等于 <小于 <=小于等于 =等于 <>不等于(还可以这么写:!=) 案例阶段: ①.查询员工号为200的员工的姓名、薪资和入职时间? select last_name,salary,hire_date from employees where employee_id = 200; ②.查询工资大于80
hankleo
2020/09/16
3940
相关推荐
Oracle学习笔记:oracle+110个常用函数
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验