两道SQL面试题引出listagg函数:

1. 用一条sql求出每个部门(emp表)的最大工资和最小工资,以及最大工资和最小工资的员工姓名。

(注:一次表扫描。同一个部门最大工资或最小工资的人可能不止一个)。

2. 需求:有时为了方便打印,会要求多行多列打印,如打印emp.ename列,类似下面这样显示:

ALLEN  JONES  MARTIN  SMITH    WARD

BLAKE  CLARK  KING    SCOTT  TURNER

ADAMS FORD   JAMES     MILLER

listagg函数是oracle11.2以后推出的一个新函数,使用该函数实现了行转列的功能,该数据与wmsys.wm_concat函数功能类似。
简单的说就是在分组合并后,把某列数据逐个枚举出来,其实也是一个行转列的效果。

如下,原始数据:

实现效果:

sql语句举例说明:

select nation,  listagg(city,',') within group (order by  city) as city

from test

group by nation

1:使用该函数必须的进行分组(group by 或使用分析函数进行分组)
2:listagg函数第一个参数表示需要进行枚举的字段,第二个参数表示枚举数据的分隔符
3:对于枚举的字段同时还需要排序和分组within group(order by xx)

利用网络上的例子:

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) city
from temp
group by nation;

--利用wmsys.wm_concat实现相似的效果

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,wmsys.wm_concat(city)
from temp
group by nation;

wmsys.wm_concat函数默认枚举的数据是','分隔开的,而listagg可以自定义分隔符

--利用over(partition by XXX) 分析函数实现分组产生以上效果

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) over (partition by nation) city
from temp;

listagg函数作为分析函数的一部分存在。

理解完listagg函数上面的面试题也就容易多了,如下:

1. 用一条sql求出每个部门(emp表)的最大工资和最小工资,以及最大工资和最小工资的员工姓名。
   (注:一次表扫描。同一个部门最大工资或最小工资的人可能不止一个)。

   select  deptno,
max(sal) max_sal,
listagg(decode(rn1, , ename, null), ',') within group(order by ename) max_sal_ename,
min(sal) min_sal,
listagg(decode(rn2, , ename, null), ',') within group(order by ename) min_sal_ename
from
(select deptno,
ename,
sal,
dense_rank() over(partition by deptno order by sal desc) rn1,
dense_rank() over(partition by deptno order by sal) rn2
from emp)
where rn1 = or rn2 =
group by deptno;

2. 需求:有时为了方便打印,会要求多行多列打印,如打印emp.ename列,类似下面这样显示:
    ALLEN  JONES  MARTIN  SMITH    WARD
    BLAKE  CLARK  KING       SCOTT  TURNER
    ADAMS FORD   JAMES     MILLER

    select deptno,listagg(ename,',') within group(order by ename)
from emp t group by t.deptno; select wmsys.wm_concat(listagg(ename,',') within group(order by ename))
from emp t group by t.deptno;

参考:
http://www.2cto.com/database/201304/204096.html
http://www.2cto.com/database/201210/161494.html
http://dacoolbaby.iteye.com/blog/1698957
http://www.itpub.net/thread-1912275-1-1.html

理解listagg函数的更多相关文章

  1. 深入理解javascript函数系列第一篇——函数概述

    × 目录 [1]定义 [2]返回值 [3]调用 前面的话 函数对任何一门语言来说都是一个核心的概念.通过函数可以封装任意多条语句,而且可以在任何地方.任何时候调用执行.在javascript里,函数即 ...

  2. 深入理解javascript函数系列第二篇——函数参数

    × 目录 [1]arguments [2]内部属性 [3]函数重载[4]参数传递 前面的话 javascript函数的参数与大多数其他语言的函数的参数有所不同.函数不介意传递进来多少个参数,也不在乎传 ...

  3. 深入理解javascript函数系列第三篇——属性和方法

    × 目录 [1]属性 [2]方法 前面的话 函数是javascript中的特殊的对象,可以拥有属性和方法,就像普通的对象拥有属性和方法一样.甚至可以用Function()构造函数来创建新的函数对象.本 ...

  4. Oracle11.2新特性之listagg函数 (行列转换)

    SELECT regexp_substr('公司1,贵公司2', '[^,]+', 1, LEVEL, 'i') FROM dualCONNECT BY LEVEL <= length('公司1 ...

  5. listagg 函数

    listagg 函数--oracle 11g release 2 转载:http://xpchild.blog.163.com/blog/static/10180985920108485721969/ ...

  6. 深入理解JS函数中this指针的指向

    函数在执行时,会在函数体内部自动生成一个this指针.谁直接调用产生这个this指针的函数,this就指向谁. 怎么理解指向呢,我认为指向就是等于.例如直接在js中输入下面的等式: console.l ...

  7. oracle 11g wm_concat 、 listagg 函数的使用(合并数据)

    方法一 wn_concat() 函数 1.把以下图中Name一样的数据合并为一条,而且NO的值要这样显示如 C.1,C.2 2.实现这种效果的操作如下,先把Name的值进行分组(group by),再 ...

  8. 理解JavaScript函数参数

    前面的话 javascript函数的参数与大多数其他语言的函数的参数有所不同.函数不介意传递进来多少个参数,也不在乎传进来的参数是什么数据类型,甚至可以不传参数. arguments javascri ...

  9. 深入理解javascript函数系列第一篇

    前面的话 函数对任何一门语言来说都是核心的概念.通过函数可以封装任意多条语句,而且可以在任何地方.任何时候调用执行.在javascript里,函数即对象,程序可以随意操控它们.函数可以嵌套在其他函数中 ...

随机推荐

  1. [转载]void及void*的深度剖析

    void的含义 void即"无类型",void *则为"无类型指针",可以指向任何数据类型. void指针使用规范 ①void指针可以指向任意类型的数据,亦即可 ...

  2. ajax上传

    使用FormData,进行Ajax请求并上传文件:具体代码如下: html代码: <!DOCTYPE html><html lang="en"><he ...

  3. Dev 控件问题多少

    150702  编译BPL_MonitorView.bpl包发现提示找不到cxBarEditItemD16包, =>我将此包和往下的 dxSkin**包都尝试性删除,编译提示要加载包,点击确定, ...

  4. 字体和壁纸合并后再更改壁纸--《用delphi开发共享软件》-15.2桌面提示器

    procedure TFrmPlay.mnDeskPicClick(Sender: TObject); Var s:String; i:Integer; begin //s:=Path+'SetPic ...

  5. wpf ,tooltip的style

    <Style x:Key="MyToolTipStyle" TargetType="ToolTip"> <Setter Property=&q ...

  6. ccc 旋转

    cc.Class({ extends: cc.Component, properties: { moveSpeed: 100, rotationSpeed: 90 }, // use this for ...

  7. Node.js 手册查询-5-Ejs 方法

    express 中使用 //设置模板目录 app.set('views', path.join(__dirname, 'views')); //设置模板引擎 app.set('view engine' ...

  8. JS保留小数点(四舍五入、四舍六入)实例

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <hea ...

  9. 20145308刘昊阳 《Java程序设计》实验三 敏捷开发与XP实践 实验报告

    20145308刘昊阳 <Java程序设计>实验三 敏捷开发与XP实践 实验报告 实验名称 敏捷开发与XP实践 实验内容 XP基础 XP核心实践 相关工具 统计的PSP(Personal ...

  10. [Leetcode|SQL] Combine Two Tables

    Table: Person +-------------+---------+ | Column Name | Type | +-------------+---------+ | PersonId ...