SQL Fundamentals || Oracle SQL语言

子查询(基础)

1、认识子查询

2、WHERE子句中使用子查询

3、在HAVING子句中使用子查询

4、在FROM子句中使用子查询

5、在SELECT子句中使用子查询

6、WITH子句

子查询(进阶)

7、分析函数

8、行列转换

9、设置数据层次

八、行列转换

  • pivot和unpivot函数是Oracle 11g增加的新函数,利用此函数可以实现行列转换操作
  • 按照原始方式实现,使用通用函数中的DECODE()函数

列字段的处理 SQL

——Case:用于实现多条件判断,在WHEN之后编写条件,而在THEN之后编写条件满足的显示操作,如果都不满足则使用ELSE中的表达式处理

——DECODE:多值判断,如果某一个列(或某一个值)与判断值相同,则使用指定的显示结果输出,如果没有满足条件,则显示默认值

SQL> select deptno,sum(sal) from emp group by deptno;

Select

case

when deptno=10 then 'ACCOUNTING'

when deptno=20 then 'RESERCH'

when deptno=30 then 'SALES'

end,

sum(sal) from emp

group by deptno

DECODE()函数语法结构:

decode (expression, search_1, result_1)
decode (expression, search_1, result_1, search_2, result_2)
decode (expression, search_1, result_1, search_2, result_2, ...., search_n, result_n)

decode (expression, search_1, result_1, default)
decode (expression, search_1, result_1, search_2, result_2, default)
decode (expression, search_1, result_1, search_2, result_2, ...., search_n, result_n, default)

比较表达式和搜索字,如果匹配,返回结果;如果不匹配,返回default值;如果未定义default值,则返回空值。

select

decode(deptno,

10, 'ACCOUNTING',

20, 'RESERCH',

30, 'SALES'

),

sum(sal) from emp

group by deptno

DECODE行转列

SQL> select job,ename,sal from emp where job='MANAGER';

JOB       ENAME             SAL

--------- ---------- ----------

MANAGER   JONES            2975

MANAGER   BLAKE            2850

MANAGER   CLARK            2450

SQL> select job,decode(ename,'BLAKE',SAL) BLAKE,decode(ename,'JONES',SAL) JONES,decode(ename,'CLARK',SAL) CLARK from emp where job='MANAGER';

JOB            BLAKE      JONES      CLARK

--------- ---------- ---------- ----------

MANAGER                    2975

MANAGER         2850

MANAGER                               2450

SQL> select job,sum(decode(ename,'BLAKE',SAL)) BLAKE,sum(decode(ename,'JONES',SAL)) JONES,sum(decode(ename,'CLARK',SAL)) CLARK from emp where job='MANAGER' group by job;

JOB            BLAKE      JONES      CLARK

--------- ---------- ---------- ----------

MANAGER         2850       2975       2450

SQL> select job,avg(decode(ename,'BLAKE',SAL)) BLAKE,max(decode(ename,'JONES',SAL)) JONES,min(decode(ename,'CLARK',SAL)) CLARK from emp where job='MANAGER' group by job;

JOB            BLAKE      JONES      CLARK

--------- ---------- ---------- ----------

MANAGER         2850       2975       2450

查询每个部门中各个职位的总工资 —— 按照部门编号及职位进行分组

SELECT deptno , job , SUM(sal)

FROM emp

GROUP BY deptno , job ;

查询每个部门中各个职位的总工资 —— 将多条工资统计信息放在一行上进行显示

SELECT deptno ,

SUM(DECODE(job, 'PRESIDENT' , sal , 0 )) PRESIDENT_JOB ,

SUM(DECODE(job, 'MANAGER' , sal , 0)) MANAGER_JOB ,

SUM(DECODE(job , 'ANALYST' , sal , 0 )) ANALYST_JOB ,

SUM(DECODE(job , 'CLERK' , sal, 0 )) CLERK_JOB ,

SUM(DECODE(job , 'SALESMAN' , sal , 0)) SALESMAN_JOB

FROM emp

GROUP BY deptno ;

DECODE()函数是ORACLE自己的特色,如没有DECODE()函数,

一般数据库利用SELECT子句使用子查询方式完成.

SELECT temp.dno,SUM(manager_job),SUM(clerk_job)

FROM(

SELECT deptno dno,

(SELECT SUM(sal) FROM emp WHERE job='MANAGER' AND empno=e.empno) manager_job,

(SELECT SUM(sal) FROM emp WHERE job='CLERK' AND empno=e.empno) clerk_job

FROM emp e) temp

GROUP BY temp.dno;

  • 在Oracle 11g版本之后,专门增加了pivot和unpivot两个转换函数

pivot函数

语法:

SELECT * | 列 [别名] ...

FROM 子查询

PIVOT (

统计函数(列)s FOR 转换列名称 IN (

内容1 [[AS] 别名] ,

内容2 [[AS] 别名] ,

...

内容n [[AS] 别名]

)

)

[WHERE 条件(s)]

[GROUP BY 分组字段1 , 分组字段2 , ….]

[HAVING 过滤条件(s)]

[ORDER BY 排序字段 ASC|DESC] ;

范例1:查询总工资,(注意该有逗号的地方有逗号,不该有的时候不要有)

SELECT *

FROM

(SELECT deptno , job , sal FROM emp)

PIVOT (

SUM(sal)

FOR job IN (

'PRESIDENT' AS president_job ,

'MANAGER' AS manager_job ,

'ANALYST' AS analyst_job ,

'CLERK' AS clerk_job ,

'SALESMAN' AS salesman_job

)

)

ORDER BY deptno ;

范例2:PIVOT函数还可以使用一个ANY变为XML数据显示:

SELECT *

FROM

(SELECT deptno, job,sal FROM emp)

PIVOT XML(

SUM(sal) FOR job IN(ANY)

)

ORDER BY deptno;·

范例3、查询更多信息,总工资,最高,最低的工资,利用分析函数就可以了.(这里只有一个统计函数SUM(sal))

SELECT * FROM (

SELECT job ,deptno , sal,

SUM(sal) OVER(PARTITION BY deptno) sum_sal ,

MAX(sal) OVER(PARTITION BY deptno) max_sal ,

MIN(sal) OVER(PARTITION BY deptno) min_sal

FROM emp)

PIVOT (

SUM(sal)

FOR job IN (

'PRESIDENT' AS president_job ,

'MANAGER' AS manager_job ,

'ANALYST' AS analyst_job ,

'CLERK' AS clerk_job ,

'SALESMAN' AS salesman_job

)

) ORDER BY deptno ;

范例4、使用多个统计函数(SUM(sal) l , MAX(sal) ),查询出每个部门不同职位的总工资,和每个部门不同职位的最高工资(仅对job字段实现分组)

SELECT * FROM (SELECT deptno , job , sal FROM emp)

PIVOT (

SUM(sal) AS sum_sal , MAX(sal) AS sum_max

FOR job IN (

'PRESIDENT' AS president_job ,

'MANAGER' AS manager_job ,

'ANALYST' AS analyst_job ,

'CLERK' AS clerk_job ,

'SALESMAN' AS salesman_job

)

) ORDER BY deptno ;

范例5、设置多个统计列(job, sex)

ALTER TABLE emp ADD(sex VARCHAR2(10) DEFAULT 'male');

UPDATE emp SET sex='female' WHERE TO_CHAR(hiredate,'yyyy')='1981';

COMMIT;

SELECT * FROM (SELECT deptno , job , sal , sex FROM emp)

PIVOT (

SUM(sal) AS sum_sal , MAX(sal) AS sum_max

FOR (job, sex) IN (

('MANAGER','男') AS manager_male_JOB ,

('MANAGER','女') AS manager_female_JOB ,

('CLERK','男') AS clerk_male_JOB ,

('CLERK','女') AS clerk_female_JOB

)

) ORDER BY deptno ;

unpivot函数

语法:

SELECT * | 列 [别名] ...

FROM 子查询

UNPIVOT [INCLUDE NULLS | EXCLUDE NULLS](

统计函数(列)s FOR 转换列名称 IN (

内容1 [[AS] 别名] ,

内容2 [[AS] 别名] ,

...

内容n [[AS] 别名]

)

)

[WHERE 条件(s)]

[GROUP BY 分组字段1 , 分组字段2 , ….]

[HAVING 过滤条件(s)]

[ORDER BY 排序字段 ASC|DESC] ;

INCLUDE NULLS:列变为行转换之后保留所有的null数据;

EXCLUDE NULLS(默认):列变为行转换之后不保留null数据。

范例1,

EXCLUDE NULLS(默认):列变为行转换之后不保留null数据。

WITH temp AS (

SELECT * FROM (SELECT deptno , job , sal FROM emp)

PIVOT (

SUM(sal)

FOR job IN (

'PRESIDENT' AS PRESIDENT_JOB ,

'MANAGER' AS MANAGER_JOB ,

'ANALYST' AS ANALYST_JOB ,

'CLERK' AS CLERK_JOB ,

'SALESMAN' AS SALESMAN_JOB

)

) ORDER BY deptno )

SELECT * FROM temp

UNPIVOT (

sal_sum FOR job IN (

president_job AS 'PRESIDENT' ,

manager_job AS 'MANAGER' ,

analyst_job AS 'ANALYST' ,

clerk_job AS 'CLERK' ,

salesman_job AS 'SALESMAN'

) ) ORDER BY deptno ;

范例2,显示所有数据

INCLUDE NULLS:列变为行转换之后保留所有的null数据;

WITH temp AS (

SELECT * FROM (SELECT deptno , job , sal FROM emp)

PIVOT (

SUM(sal)

FOR job IN (

'PRESIDENT' AS PRESIDENT_JOB ,

'MANAGER' AS MANAGER_JOB ,

'ANALYST' AS ANALYST_JOB ,

'CLERK' AS CLERK_JOB ,

'SALESMAN' AS SALESMAN_JOB

)    ) ORDER BY deptno )

SELECT * FROM temp

UNPIVOT INCLUDE NULLS(

sal_sum FOR job IN (

president_job AS 'PRESIDENT' ,

manager_job AS 'MANAGER' ,

analyst_job AS 'ANALYST' ,

clerk_job AS 'CLERK' ,

salesman_job AS 'SALESMAN'

) ) ORDER BY deptno ;

九、设置数据层次

LEVEL可以设置数据层次结构。

设置层次函数

  • 层次查询是一种较为确定数据行之间关系结构的一种操作,
  • 例如,在现实社会的工作之中一定会存在“管理层”、“职员层”这样的基本分层关系,在学校也会分为“教学管理层”、“教师层”、“学生层”这样三种层次结构。
  • 在Oracle之中用户也可以利用其自身所带的工具实现这样的层次组织。

语法:

LEVEL ...

CONNECT BY [NOCYCLE] PRIOR 连接条件

[START WITH 开始条件]

LEVEL

可以根据数据所处的层次结构实现自动的层次编号,例如:1、2、3;

CONNECT BY

指的是数据之间的连接,

例如:雇员数据依靠mgr找到其领导,就是一个连接条件,其中NOCYCLE需要结合CONNECT_BY_ISCYCLE伪列确定出父子节点循环关系;

START WITH

根节点数据的开始条件;

分层的基本关系

SELECT empno,ename,mgr,LEVEL

FROM emp

CONNECT BY PRIOR empno=mgr

START WITH mgr IS NULL ;

使用LPAD处理一下LEVEL

SELECT empno,LPAD('|- ' , LEVEL * 2 , ' ') || ename empname ,mgr,LEVEL

FROM emp

CONNECT BY PRIOR empno=mgr

START WITH mgr IS NULL ;

 

CONNECT_BY_ISLEAF伪列(判断根节点、叶节点)

一颗树状结构之中,节点会分为两种:根节点、叶子节点,

用户可以利用“CONNECT_BY_ISLEAF”伪列判断某一个节点是根节点还是叶子节点,

,就是叶子节点。

示例:利用“CONNECT_BY_ISLEAF”判断某一个节点是根节点还是叶子节点

SELECT empno,LPAD('|- ' , LEVEL * 2 , ' ') || ename empname ,mgr,LEVEL ,

DECODE (CONNECT_BY_ISLEAF , 0 , '根节点' , 1 , '   叶子节点') isleaf

FROM emp

CONNECT BY PRIOR empno=mgr

START WITH mgr IS NULL ;

CONNECT_BY_ROOT 列(判断某一字段在本次分层中的根节点数据名称)

CONNECT_BY_ROOT的主要作用是取得某一个字段在本次分层之中的根节点数据名称,

例如:如果按照领导层次划分,则所有数据的根节点都应该是KING。

SELECT empno,ename,mgr,LEVEL,LPAD('|-',LEVEL,' ') || ename empname,LEVEL,

CONNECT_BY_ROOT ename

FROM emp

CONNECT BY PRIOR empno=mgr

START WITH mgr IS NULL ;-------------从mgr为空这个值开始

SELECT empno,LPAD('|- ' , LEVEL * 2 , ' ') || ename empname ,mgr,LEVEL ,

CONNECT_BY_ROOT ename

FROM emp

CONNECT BY PRIOR empno=mgr

START WITH empno=7566 ;

SYS_CONNECT_BY_PATH (列 , char)函数

利用“SYS_CONNECT_BY_PATH()”函数按照给出的节点关系,自动的将当前根节点中的所有相关路径进行显示

使用SYS_CONNECT_BY_PATH()函数取得节点路径信息

SELECT empno,LPAD('|- ' , LEVEL * 2 , ' ') || SYS_CONNECT_BY_PATH(ename,' => ') empname ,mgr,LEVEL ,

DECODE (CONNECT_BY_ISLEAF , 0 , '根节点' , 1 , '   叶子节点') isleaf

FROM emp

CONNECT BY PRIOR empno=mgr

START WITH mgr IS NULL ;

去掉某一节点的显示

SELECT empno,LPAD('|- ' , LEVEL * 2 , ' ') || SYS_CONNECT_BY_PATH(ename,' => ') empname ,mgr,LEVEL ,

DECODE (CONNECT_BY_ISLEAF , 0 , '根节点' , 1 , '   叶子节点') isleaf

FROM emp

CONNECT BY PRIOR empno=mgr AND empno!=7698

START WITH mgr IS NULL ;

ORDER SIBLINGS BY 字段

在使用层次查询进行数据显示时,如果用户直接使用ORDER BY子句进行指定字段的排序,有可能会破坏数据的组成结构

破坏程序结构的显示

SELECT ename,LPAD('|- ' , LEVEL * 2 , ' ') || ename empname ,LEVEL ,

DECODE (CONNECT_BY_ISLEAF , 0 , '根节点' , 1 , '   叶子节点') isleaf

FROM emp

CONNECT BY PRIOR empno=mgr

START WITH mgr IS NULL

ORDER BY ename ;

利用“ORDER SIBLINGS”保持层次关系

SELECT ename,LPAD('|- ' , LEVEL * 2 , ' ') || ename empname ,LEVEL ,

DECODE (CONNECT_BY_ISLEAF , 0 , '根节点' , 1 , '   叶子节点') isleaf

FROM emp

CONNECT BY PRIOR empno=mgr

START WITH mgr IS NULL

ORDER siblings BY ename ;

CONNECT_BY_ISCYCLE伪列

在进行数据层次设计的过程之中,最为重要根据指定的数据列确定数据间的层次关系,但是有时候也可能出现死循环,

例如:KING的领导是BLAKE,而BLAKE的领导是KING就表示一个循环关系,为了判断循环关系的出现,在Oracle中也提供了一个CONNECT_BY_ISCYCLE伪列,来判断是否会出现循环,如果出现循环,则显示1,没有出现循环,则显示0。

同时如果要想判断是否为循环节点,则还需要“NOCYCLE”的支持。

判断循环

SELECT ename,LPAD('|- ' , LEVEL * 2 , ' ') || ename empname ,LEVEL ,

DECODE (CONNECT_BY_ISLEAF , 0 , '根节点' , 1 , '   叶子节点') isleaf ,

DECODE(CONNECT_BY_ISCYCLE , 0 , '【√】没有循环' , 1 , '〖×〗存在循环') iscycle

FROM emp

CONNECT BY NOCYCLE PRIOR empno=mgr

START WITH empno=7839

ORDER siblings BY ename ;

SQL Fundamentals: 子查询 || 行列转换(PIVOT,UNPIVOT,DECODE),设置数据层次(LEVEL...CONNECT BY)的更多相关文章

  1. SQL Server中行列转换 Pivot UnPivot

    SQL Server中行列转换 Pivot UnPivot PIVOT用于将列值旋转为列名(即行转列),在SQL Server 2000可以用聚合函数配合CASE语句实现 PIVOT的一般语法是:PI ...

  2. SQL Fundamentals: 子查询 || 分析函数(PARTITION BY,ORDER BY, WINDOWING)

    SQL Fundamentals || Oracle SQL语言 子查询(基础) 1.认识子查询 2.WHERE子句中使用子查询 3.在HAVING子句中使用子查询 4.在FROM子句中使用子查询 5 ...

  3. SQL Fundamentals: 子查询 || WHERE,HAVING,FROM,SELECT子句中使用子查询,WITH子句

    SQL Fundamentals || Oracle SQL语言 子查询(基础) 1.认识子查询 2.WHERE子句中使用子查询 3.在HAVING子句中使用子查询 4.在FROM子句中使用子查询 5 ...

  4. SQL Server中行列转换 Pivot UnPivot

    PIVOT用于将列值旋转为列名(即行转列),在SQLServer 2000可以用聚合函数配合CASE语句实现 PIVOT的一般语法是:PIVOT(聚合函数(列)FOR 列 in (-) )AS P 完 ...

  5. SQLServer中行列转换Pivot UnPivot

    PIVOT用于将列值旋转为列名(即行转列),在SQL Server 2000可以用聚合函数配合CASE语句实现 PIVOT的一般语法是:PIVOT(聚合函数(列) FOR 列 in (…) )AS P ...

  6. 多列的行列转换(PIVOT,UNPIVOT)

    形式1 形式2 形式3 有时候可能会有这样的需求: 将一张表的所有列名转做为数据的一列数据,将一列数据作为整张表的列名 当列比较多时,只用PIVOT是解决不了的,经过研究,需要将UNPIVOT 和 P ...

  7. 【转】Spark实现行列转换pivot和unpivot

    背景 做过数据清洗ETL工作的都知道,行列转换是一个常见的数据整理需求.在不同的编程语言中有不同的实现方法,比如SQL中使用case+group,或者Power BI的M语言中用拖放组件实现.今天正好 ...

  8. SQL的子查询操作

    对于表中的每一个记录,我们有时候需要提取特殊的或者你需要的记录,要提前做一个表的筛选,之后再对你选出的记录做一个修改,此时你必须使用SQL的子查询操作.如:修改id=5的记录的strContent字段 ...

  9. C#构造方法(函数) C#方法重载 C#字段和属性 MUI实现上拉加载和下拉刷新 SVN常用功能介绍(二) SVN常用功能介绍(一) ASP.NET常用内置对象之——Server sql server——子查询 C#接口 字符串的本质 AJAX原生JavaScript写法

    C#构造方法(函数)   一.概括 1.通常创建一个对象的方法如图: 通过  Student tom = new Student(); 创建tom对象,这种创建实例的形式被称为构造方法. 简述:用来初 ...

随机推荐

  1. SpringBoot------集成PageHelper分页功能

    添加MyBatis的代码,地址 https://www.cnblogs.com/tianhengblogs/p/9537665.html 修改以下部分: 1.添加MyBatisConfig packa ...

  2. [转]Tomcat的部署

    1.1 Context descriptors Tomcat4中的Manager和Admin管理工具其实就是利用它来部署的.在Tomcat5中提出了Context descriptor这个概念,且为其 ...

  3. [AX]AX2012 R2 EP员工自助服务中的产品不能显示图片的问题

    在员工自助服务EP站点中员工可以通过Order products自助提交采购申请,在正确设置员工采购目录后会罗列出允许员工购买的产品,每个产品都可带有图片,我们可以通过Product image来为产 ...

  4. windows 下获取当前进程的线程数量

    #include <TlHelp32.h> int get_thread_amount() { ; ]; PROCESSENTRY32 pe32; pe32.dwSize = sizeof ...

  5. jQuery Colorbox弹窗插件使用教程小结、属性设置详解以及colorbox关闭

    jQuery Colorbox是一款弹出层,内容播放插件,效果极佳,当然我主要是用来弹出图片啦. jQuery Colorbox不仅有弹性动画效果,淡入淡出效果,幻灯片播放,宽度自定义,还能够ajax ...

  6. Extended VM Disk In VirtualBox or VMware (虚拟机磁盘扩容)

    First, Clean VM all snapshot, and poweroff your VM. vmdk: vmware-vdiskmanager -x 16GB myDisk.vmdk vd ...

  7. IDEA试用期结束激活问题

    1.试用期结束,出现IDEA License Activation界面 2.IntelliJ Idea 2017 免费激活方法 方法1. 到网站 http://idea.lanyus.com/ 获取注 ...

  8. Windows 系统提示“内存不足”的原因及解决方法

         Windows 系统提示“内存不足”的原因及解决方法 windows XP vista 及windows 7系统的电脑有时候会出现系统提示“内存不足”,这是由多方面原因造成的.本文具体分析下 ...

  9. 【python3】window下 vscode 配置 python3开发环境

    本文以python3.7 为例 一 下载python3 url : https://www.python.org/downloads/windows/ 提示: 安装过程中.记得勾选  添加环境变量 二 ...

  10. Host 'xxx.xx.xxx.xxx' is not allowed to connect to this MySQL server

    改表法.可能是你的帐号不允许从远程登陆,只能在localhost.这个时候只要在localhost的那台电脑,登入mysql后,更改 "mysql" 数据库里的 "use ...