文章目录

  • 批量生成 SQL 语句/拼接字符串
  • 多表关联查询 + where 子句
    • 示例(一)
    • 示例(二)
  • 普通的表间内连接查询语句
    • 关键字 distinct 用法说明
  • Oracle 数据库的分组排序查询
  • Oracle 数据库 cast 函数
  • Oracle 数据库 sum 函数的高级用法
  • Oracle 数据库多层子查询嵌套查询
  • 关联子查询
    • 数据库如何把纵向列表转换成横向列表

批量生成 SQL 语句/拼接字符串

select 'update t_pf_menu set a1='''||t.a1||''' where a2='''|| t.a2||''';'
from tesst t;
select 'update t_busop set busname='''||t.busname||''',icon='''||t.icon||''' where busopid='''|| t.busopid||''';'
from lwx t;

SQL 语句解释:

|| 是表示两段字符串拼接起来,' ' 里面是拼接的字符串, ' '' ' 表示字符串里面有个单引号,'' 表示一个单引号哦。
t.a1 表示取 t 表的 a1 字段的值,注意变量不要加任何的引号哦。

注意:
Oracle 数据库字符串拼接符号 ||,而MySQL 数据库的字符串拼接使用函数 concat(str1,str2),str1、str2 是指要拼接的两个字符串

多表关联查询 + where 子句

示例(一)

select s.name,s.age,c.course_name
from student s
left outer join course c
on s.course_id=c.course_id
where c.course_id='0707';

上述查询语句执行过程如下:

  1. 先打开表 student 和 course
  2. 接着根据关联条件(s.course_id=c.course_id)将 student 和 course 将两张表进行关联
  3. 接着将匹配结果生成一张虚表,即将符合条件的两张表的数据合并成一张虚表 v1
  4. 再根据 where 条件把虚表 v1 中符合 c.course_id='0707' 的记录筛选出来,生成虚表 v2
  5. 最后执行 select 子句把指定字段的数据获取到,生成虚表 v3,v3 就是最后的查询结果

左外连接 left outer join 执行效果说明:

left outer join 的查询结果是这样的,如果匹配成功的那么两张表的相关字段的数据会提取出来,如果匹配不成功的,则左边的数据提取出来,右边表的相应字段值则为空。

错误理解:

这个 where 子句并不是先对 course 表进行筛选再和 student 表进行关联查询,而是进行关联匹配的同时进行筛选,匹配成功且符合筛选条件的记录才提取出来,如果只是匹配成功但是不符合筛选条件的剔除掉。

示例(二)

 select cmcltname,jurperson,special,d.name,ecotype,depcode from $prdline.securiorg s left outer join $platform.t_pf_datadict d on s.tecgrd=d.code where d.ddfld='tecgrd';

执行过程简单说明:
数据库是按照这样的顺序来执行 SQL 语句的,首先 securiorg 和 t_pf_datadict 两张表通过 s.tecgrd=d.code 关联条件进行做左连接,这样就得到连接后的结果集,再执行 where 语句进行筛选,再执行 select 语句得到最后想要的结果集。

普通的表间内连接查询语句

select distinct e.deptno,d.dname from emp_lwx e inner join dept_lwx d on e.deptno=d.deptno;

分析上述 SQL 语句的内部执行顺序如下:

  1. 数据库先执行 from,打开表 emp_lwx 和 dept_lwx
  2. 接着执行 on,根据关联字段把两张表关联起来
  3. 接着执行 inner join,把匹配的数据取出生成一张虚表 v1
  4. 接着执行 select 子句,在虚表 v1 中取出相关的数据生成虚表 v2
  5. 接着执行 distinct,将虚表 v2 中 deptno 和 dname 都重复的数据过滤掉,生成虚表 v3,此虚表 v3 就是最后的查询结果

关键字 distinct 用法说明

select distinct deptno,job from emp_lwx;

distinct 关键字不是作用在字段 deptno 上,在执行 select 子句的时候,数据库是这样判断的,取出 deptno 和 job 的数据,这两个字段的数据联合起来在结果集中是唯一的就可以了,这个两个字段的数据就构成结果集中的一条记录,只要这条记录在整个结果集中是唯一的就OK了。

Oracle 数据库的分组排序查询

SELECT T.ENTITYID,T.CREDATE,T.EXACTCRETIME,ROW_NUMBER() OVER(PARTITION BY T.ENTITYID ORDER BY CREDATE DESC,EXACTCRETIME DESC) AS RNUM
FROM HYT2PRDHN.TASKED T;

说明:
先执行 FROM,接着执行 SELECT,接着执行 PARTITION BY,最后执行 ORDER BY。对 SELECT 出来的结果集按 ENTITYID 进行分组,每组再按 CREDATE 和 EXACTCRETIME 排序,顺序号的字段名为 RNUM,查询得到的结果如下图所示:

Oracle 数据库 cast 函数

SELECT CODE,NAME,CAST(CASE WHEN CODE LIKE '%000' THEN 1 WHEN CODE LIKE '%00' THEN 2 ELSE 3 END AS VARCHAR2(3)) AS LEV
FROM T_PF_DATADICT WHERE DDFLD='BNSCOPE' AND CODE IN ('08000','08100','08101','08102','08103','08200','08201','08300','08301')
ORDER BY CODE

解读:

CAST函数的作用是类型转换,在此就是将LEV 字段的数据类型转换成VARCHAR2(3)

Oracle 数据库 sum 函数的高级用法

 select depcode,sum(case when BILLSTATE=1 then 1 else 0 end) as 未使用,sum(case when BILLSTATE in (2,3,4) then 1 else 0 end) as 已使用,sum(case when BILLSTATE in (5) then 1 else 0 end) as 已遗失 from BCBILLSTOCK group by depcode;

解读:

先对整个表进行遍历分组,然后判断每组里面每条记录 BILLSTATE 字段的值,如果是 1 则累加 1 ,否则累加 0,最后的累加值显示一列,列名为:未使用;如果是2或3或4则将累加 1,否则累加 0,最后的值显示一列,列名为:已使用;如果是 5 则累加 1,否则累加 0,最后的值显示一列,列名为:已遗失。

Oracle 数据库多层子查询嵌套查询

SELECT DEPNAME 运管机构,SUM(已作废) 已作废,SUM(已反馈) 已反馈,SUM(未使用) 未使用,SUM(已使用) 已使用
FROM
(SELECT DEPNAME,CASE 牌证状态 WHEN '已作废' THEN TOTAL END AS 已作废,CASE  牌证状态 WHEN '已反馈' THEN TOTAL END AS 已反馈,CASE 牌证状态 WHEN '未使用' THEN TOTAL END AS 未使用,CASE 牌证状态 WHEN '已使用' THEN TOTAL END AS 已使用
FROM
(SELECT D1.DEPNAME,B1.牌证状态,B1.TOTAL
FROM (SELECT T1.DEPCODE, CASE BILLSTATE WHEN '2' THEN '已使用' WHEN '3' THEN '已作废' WHEN '4' THEN '已反馈' WHEN '5' THEN '遗失' ELSE '未使用' END AS 牌证状态,SUM(CNT) TOTAL
FROM BCBILLSTOCK T1
GROUP BY DEPCODE,BILLSTATE) B1
LEFT JOIN HYT2PRDHN.T_PF_DEP D1
ON B1.DEPCODE=D1.DEPCODE))
GROUP BY DEPNAME;

注意: 先对某张表进行筛选再关联其它表是不可以的,对某个表先进行分组再筛选也是不可以的,会报错

关联子查询

select ename, salary, deptno from emp_xxx a where salary < ( select avg(nvl(salary,0))
from emp_xxx where deptno = a.deptno; // 子查询需要依赖主查询传递过来的参数 a.deptno

解读:
数据库的指针先指向 emp_xxx 的第一条记录,然后将当前记录的deptno的值传递给子查询,接着数据库开始执行子查询,计算出参数deptno的值所对应的部门的平均工资,接着又回到主查询判断当前记录的salary值是否小于平均工资,如果小于则添加到结果集,接着指针移到下条记录,重复上一次的查询动作,如果当前记录不小于平均工资,则直接将指针移到下条记录,重复上一次的查询动作。这样就可以查询出所有薪水比本部门平均工资低的员工数据。

我们知道数据库服务器执行SQL语句是有按照先后顺序的,例如:select ename,salary from emp_lwx where salary >3000;
顺序是这样的,数据库服务器首先打开emp_lwx表,然后执行where语句,按照where子句的条件来筛选符合条件的记录,服务器是对整个表从上至下进行全盘扫描,逐条判断记录是否符合条件,然后把符合条件的记录全部放在内存的一个虚表中,然后才执行select子句的,是符合条件的记录全部筛选出来后才执行select子句,而不是筛选一条记录就执行一次select子句,当然执行select子句也是从上至下逐条取出所需的数据,如果是组函数的话,那么就逐条记录取出所需的数据后再进行函数运算的。

数据库如何把纵向列表转换成横向列表

纵向列表,如下图所示:

如何变成横向列表,如下图所示:

SQL语句是这样写的:

select o.year,(select n.amount
from ym n where n.month='1' and n.year=o.year) as m1,(select n.amount
from ym n where n.month='2' and n.year=o.year) as m2,(select n.amount
from ym n where n.month='3' and n.year=o.year) as m3,(select n.amount
from ym n where n.month='4' and n.year=o.year) as m4
from ym o group by year;

解读下:

很明显这是一个关联子查询,执行顺序是这样的,首先主查询 from ym 0 group by year 是先打开ym这张表,然后根据year字段来分组,接着执行select语句,指针先移至第一组,获取第一组的year值,也就是1991,然后执行关联子查询了,这时会把第一组的年份1991传入子查询中,那么第一个子查询就根据 month=‘1’ and year=‘1991’ 获取到相应的 amount值,字段名是m1,接着执行第二个子查询了,同样是将第一组的年份1991传入,得到相应的amont值,直到4个子查询都执行完毕,这样就得到第一条记录。那么指针就移到第二组了,同上一轮一样取出相应的值,那么最后得到的结果就是第2条记录了。

注意:这里的指针按组移动,取到年份值后分别传给四个子查询!

Oracle 数据库中较为复杂或典型的 SQL 语句的解读相关推荐

  1. 删除数据库中所有存储过程和函数的sql语句

    -删除数据库中所有存储过程和函数的sql语句 USE [TmpDb] SELECT  IDENTITY( INT,1,1 ) flag ,         [name] NAMES,xtype INT ...

  2. mysql查询低效语句_MySQL数据库中查找执行从命慢的SQL语句

    MySQL数据库中查找执行从命慢的SQL语句 (2011-09-15 08:21:35) 标签: 杂谈 去历:赛迪网 做者:Alizze 启动Mysql时减参数--log-slow-queries去挤 ...

  3. oracle数据库中最常用的sql语句

    对SQL语句进行调整,往往有一项前期工作,就是定位最常用的SQL 语句.Oracle数据库可以从多个方面取得SQL语句.如从数据库自身的存储过程或者函数中取得,也可以从前台的应用程序中取得.所以,数据 ...

  4. 一起ORACLE数据库中数据查询结果不一致问题的排查过程

    一.问题描述 在某软件开发项目中,需要在ORACLE数据库中建立十张类型相同的员工信息表tb_employeeinfo0~tb_employeeinfo9,并建立向这十张表中插入数据的存储过程.ORA ...

  5. 批量插入数据库语句java_java相关:MyBatis批量插入数据到Oracle数据库中的两种方式(实例代码)...

    java相关:MyBatis批量插入数据到Oracle数据库中的两种方式(实例代码) 发布于 2020-7-22| 复制链接 本文通过实例代码给大家分享了MyBatis批量插入数据到Oracle数据库 ...

  6. 如何从Oracle数据库中的表中获取列名(字段名)列表?

    如何从Oracle数据库中的表中获取列名(字段名)列表? 目录 如何从Oracle数据库中的表中获取列名(字段名)列表? #示例一 #示例二 示例三: #示例一 可以获取: table_name:表名 ...

  7. 导出Windows服务器下的Oracle数据库并导入到Linux服务器下的Oracle数据库中

    2019独角兽企业重金招聘Python工程师标准>>> 说明: 1.Windows Oracle数据库 操作系统:Windows Server 2008 R2 IP地址:192.16 ...

  8. oracle 数据库中(创建、解锁、授权、删除)用户

    上文我们已经建立了名为orcl66的数据库. 想要在数据库中创建.修改用户需要我们以管理员权限登录到数据库中. 首先我们通过sqlplus命令登录连接数据库. 输入sqlplus命令--用户名: sy ...

  9. Oracle数据库中的优化方案

    2019独角兽企业重金招聘Python工程师标准>>> 一. 优化oracle中的sql语句,提高运行效率 1. 选择最有效率的表名顺序(只在基于规则的优化器中有效) ORACLE的 ...

最新文章

  1. Nginx 作为web server 的优化要点
  2. 如何用hover写出顺畅的动态效果
  3. Linux命令(27):shell 结合expect,多服务器批量分发数据
  4. 3.分布式文件系统HDFS之二
  5. 2016年Android主流技术
  6. 点击按钮修改背景颜色及节点操作隔行变色案例
  7. Panasonic Programming Contest (AtCoder Beginner Contest 195) 题解
  8. mongodb防火墙配置
  9. cosine_similarity和torch.cosine_similarity速度差异(人间奇事)
  10. 供应链 信用管理 大数据_智慧供应链大数据技术架构方案(ppt)
  11. matlab gui 表面粗糙度 算法,石墨加工表面粗糙度图像评定办法
  12. 众专家推荐《移动微技(Mobile Widget)应用开发权威指南》
  13. mybatis-plus实现乐观锁
  14. 基于javaweb的在线学习系统
  15. 基于javaweb+springboot的学生学科竞赛管理管理系统设计和实现(java+springboot+ssm+maven)
  16. 枚举列表(enumerated list) ← LaTeX
  17. Linux ntp时间服务器的搭建和配置
  18. 多晴转云h_多晴转云htxt百度云
  19. 360wifi在linux系统如何使用,在树莓派上使用360WIFI(也适用于小米、百度、腾讯WIFI)...
  20. 【微信小程序开发】(三)首页banner组件使用swiper

热门文章

  1. java 迁移数据_Java 9迁移指南:七个最常见的挑战
  2. 旧访客设计模式的新生活
  3. scala本地调试_如何编写自己的Java / Scala调试器
  4. JDK 10:从Java访问Java应用程序的进程ID
  5. jar运行 osgi保存_自动化的OSGi测试运行程序
  6. 使用Dropwizard度量标准监视和测量无功应用
  7. 在单元测试和TDD中指定时间的重要性
  8. junit白盒测试 案例_JUnit通过失败测试案例
  9. sts-bundle的使用_使用WS-Trust / STS采样器扩展JMeter
  10. JSF 2.2在30秒内创建一个自定义Hello World组件