Oracle数据库基本操作(三) —— DQL相关内容说明及应用
本文所使用的查询表来源于oracle数据中scott用户中的emp员工表和dept部门表。
一、基本语法
SQL语句的编写顺序:
select 输出的列 from 表名 where 条件 group by 分组 having 分组之后的条件过滤 order by 排序;
1、伪表(dual):Oracle 对语法要求比较严格,而伪表/虚表主要用于补齐语法结构,如
select 5+5 from dual;
2、别名查询:as关键字,但可省略,如:
select ename as 姓名,job 工作 from emp;
3、去除重复数据:distinct
注意:若是多列去重,必须是每一列都相同才算重复的。
select distinct job,mgr from emp;
4、空值问题
注意:null 值不能参加与SQL四则运算
null值代表不确定的内容,未知的内容,所有值跟null进行比较,结果都为null。
-- 函数: nvl 若参数1为 null ,则返回参数2, 否则返回参数1
select nvl(null,6) from dual; -- 6
select nvl(5,6) from dual; -- 5
5、字符串拼接:
通用 concat(str1,str2) 、Oracle 特有的连接符 ||
select concat('abc','def') from dual;
select 'abc'||'def'||'xxx' from dual;
6、where条件查询
- 关系运算符: > >= = < <= != <>
- 逻辑运算符: and or not
- 其它运算符:
- between..and.. 在区间内
- in(集合) 在集合内
- is null
- is not null
- like
- >any(集合) 任意
- >all(集合) 所有
- exists(查询语句)
-- 查询名字在 'ALLEN','BLAKE','SCOTT' 集合内的员工信息
select * from emp where ename in('ALLEN','BLAKE','SCOTT');
7、模糊查询:like
- % : 匹配任意个数字符
- _ : 匹配单个字符
- escape 相当于是指定用哪个字符,作为转义字符
-- '\' 不可作为转义符
select * from emp where ename like '%$%%' escape '$';
8、排序:order by
- asc : ascend升序 默认
- desc: descend 降序
- nulls first | last
select * from emp order by comm asc nulls first;
二、单行函数
单行函数: 只对一个值进行处理,如字符串函数、数值函数、日期函数等;
-- 数值函数: ceil()向上取整, floor()向下取整, mod()取模, abs()取绝对值, round()四舍五入, trunc()截断
-- 向上取整
select ceil(-11.9) from dual; -- -11-- round 四舍五入
select round(45.926,2) from dual; -- 45.93
select round(45.926,0) from dual; --
select round(45.926,-1) from dual; --
-- trunc 截断
select trunc(45.926,2) from dual; -- 45.92
select trunc(55.926,-2) from dual; -- -- 字符串函数
-- 输出每一个员工 : 姓名:ename
select concat('姓名:',ename) from emp;
-- 长度: length
select length('hello') from dual; -- 截取字符串 : 注意: 无论是从0还是1开始,都是从第1个字符开始截取
select substr('abcdefg',0,3) from dual; -- abc -- 去除空格
select trim(' abc ') from dual;
-- 去除字符串两端指定的字符 结果: gao qian jing
select trim('X' from 'XXXgao qian jingXXXX') from dual;
-- 替换
select replace('hello','l','x') from dual; -- 日期函数: 查询当前日期
select sysdate from dual; -- 2018/1/31 18:00:03
select sysdate+1 from dual; -- 查询员工的入职周数
select emp.*,(sysdate - hiredate)/7 from emp;
-- 查询员工的入职月数
select emp.*,months_between(sysdate,hiredate) from emp;
-- 查询员工的入职年数
select emp.*,months_between(sysdate,hiredate)/12 from emp;
-- 三个月的优酷会员 , 计算几个月之后的日期
select add_months(sysdate,3) from dual; -- 字符串转数值: to_number 鸡肋
select '' + 24 from dual; --
select to_number('') + 24 from dual; -- -- 数值转字符串: 123 对数值进行格式化处理
select concat(123,'hello') from dual;
-- yyyy-mm-dd
select emp.*,to_char(sal,'$9999.9') from emp;
select to_char(1234567,'$9,999,999.99') from dual; -- 日期转字符串
select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;
-- 查询年份
select to_char(sysdate,'yyyy') from dual;
-- 查询月份
select to_char(sysdate,'mm') from dual;
-- 查询日数
select to_char(sysdate,'dd') from dual;
select to_char(sysdate,'d') from dual; -- 一个星期的第4天
select to_char(sysdate,'ddd') from dual; -- 一年过了几天
select to_char(sysdate,'day') from dual; -- wednesday
select to_char(sysdate,'dy') from dual; -- wed -- 字符转日期
select to_date('1980-01-31','yyyy-mm-dd') from dual;
-- nvl(p1,p2) 判断p1是否为null , 若为null, 则返回p2, 否则返回p1
-- nvl2(p1,p2,p3) 类似三元运算符
select nvl2(null,5,6) from dual; --
select nvl2(1,5,6) from dual; --
条件表达式:
通用写法:
case 列
when 值1 then 输出
when 值2 then 输出
when 值3 then 输出
else
end;
Oracle特有的写法:
decode(列名,if1,then1,if2,then2,default)
条件表达式使用示例:
-- 给员工表所有的员工取一个中文名称
select ename,case ename
when 'SMI%TH' then '曹贼'
when 'ALLEN' then '刘备小儿'
when 'MARTIN' then '诸葛村夫'
else
'路人甲'
end
from emp;
------------------------------
select ename,
decode(ename,'SMI%TH','曹贼','ALLEN','刘备小儿','路人乙')
from emp;
-------------------------------
select emp.*,case
when sal<1500 then '贫农'
when sal>=1500 and sal<=3000 then '中农'
else
'地主'
end 阶级
from emp;
三、多行函数
1、多行/聚合函数: count,max ,min ,avg ,sum
注意: 聚合函数在执行运算的过程中会忽略空值
-- 查询所有员工人数
select count(*) from emp; -- 查询奖金总金额
select sum(comm) from emp; -- 查询全公司平均奖金
select avg(comm) from emp;
select sum(comm)/count(*) from emp;
2、分组查询
select 分组的条件,分组之后的操作 from 表名 group by 分组条件 having 分组之后的条件过滤
本质: 先对表中数据按照分组的条件进行排序,然后再执行分组之后的运算
注意: 分组查询时: select后面只能输出分组的条件和分组之后的操作
-- 查询每个部门的平均工资
select deptno,avg(sal) from emp group by deptno; -- 查询每个部门的平均工资,并且平均高于2000
select deptno,avg(sal) from emp group by deptno having avg(sal)>2000;
3、where 和 having区别
- where 是在分组之前执行的条件过滤, 不能接聚合函数, 可以接单行函数
- having 是分组之后的条件过略,可以接聚合函数
四、多表查询
1、内连接查询
-- 同时查询两张表,多表查询,
-- 查询出的结果为笛卡尔积:表示的是两张表的乘积,结果没有实际意义
select * from emp,dept; -- 在笛卡尔积的基础上筛选出有意义的数据
-- 隐式内连接
select * from emp e,dept d where e.deptno = d.deptno; -- 显式内连接: inner join..on..
select * from emp e inner join dept d on e.deptno = d.deptno; -- 隐式内连接查询示例
-- 查询员工编号,员工姓名,员工的部门名称,工资等级, 经理编号,经理姓名,经理的部门名称,经理的工资等级
select e.empno, e.ename,d1.dname,
case s1.grade
when 1 then '一级'
when 2 then '二级'
when 3 then '三级'
when 4 then '四级'
when 5 then '五级'
end 工资等级,
e.mgr, m.ename,d2.dname,
case s2.grade
when 1 then '一级'
when 2 then '二级'
when 3 then '三级'
when 4 then '四级'
when 5 then '五级'
end 工资等级
from emp e, emp m,dept d1,dept d2,salgrade s1,salgrade s2
where e.mgr = m.empno
and e.deptno = d1.deptno
and m.deptno = d2.deptno
and e.sal between s1.losal and s1.hisal
and m.sal between s2.losal and s2.hisal;
2、外连接查询
标准/通用的写法:
左外连接: 以左表为基础,查询左表中所有的记录以及左表和右表对应的记录,若右表没有对应的记录,则显示null
left outer join..on..
右外连接:以右表为基础,查询右表中所有的记录以及左表和右表对应的记录,若左表没有对应的记录,则显示null
right outer join..on..
Oracle外连接特有的写法:
(+) : 若没有对应的记录,则添加null显示
-- 左外连接
select * from emp e left outer join dept d on e.deptno = d.deptno;
-- 使用Oracle特有写法,查询左外连接的结果
select * from emp e,dept d where e.deptno = d.deptno(+); -- 右外连接
select * from emp e right outer join dept d on e.deptno = d.deptno;
-- 使用Oracle特有写法,查询右外连接的结果
select * from emp e,dept d where e.deptno(+) = d.deptno; -- 扩展: 全外连接 full outer join
select * from emp e full outer join dept d on e.deptno=d.deptno;
五、子查询
子查询: 一个查询语句中嵌套另一个查询内容
作用: 解决复杂的查询需求
1、单行子查询:子查询出来的结果只有单个值
操作符: > >= = < <= != <>
-- 查询最高工资的员工信息
select * from emp where sal = (select max(sal) from emp);
-- 查询出比 雇员7654的工资 高,同时 和7788从事相同工作 的员工信息
select * from emp where sal > (select sal from emp where empno=7654) and job = (select job from emp where empno=7788);
2、多行子查询:子查询出来的结果有多行
操作符: in any all exists
-- 查询所有是领导的员工信息
select * from emp where empno =any(select distinct mgr from emp)
-- 查询所有不是领导的员工信息
-- 注意:子查询中的空值问题
select * from emp where empno not in(select distinct mgr from emp where mgr is not null);
select * from emp where empno != all(select distinct mgr from emp where mgr is not null);
exists(查询语句):存在的意思
- 若查询语句存在结果,则返回true
- 若查询语句不存在结果,则返回false
-- 当条件满足时相当于 1=1,不满足时相当于1=2
select * from emp where exists(select * from dept where deptno=10);
select * from emp where 1=1; select * from emp where exists(select * from dept where deptno=100);
select * from emp where 1=2;
六、SQL编写顺序与执行顺序
- SQL编写顺序
select..from..where..group by..having..order by..
- SQL执行顺序:
from..where..group by..having..select..order by..
先从表中获取数据,判断是否符合条件,对符合条件的数据就进行分组,分组完后,在组内进行判断是否符合指定条件,筛选出符合条件的数据,根据选择要求进一步筛选出需要的字段,并将所有数据根据规则进行排序。
- 关联子查询与非关联子查询执行顺序
七、伪列(oracle特有)
1、rownum : 伪列/虚列, 表示的行号,主要运用在Oralce分页查询中,借助子查询
每查询出一条满足条件的记录,数据库中默认已经存在rownum,起始值是从1开始的,每输出一条记录,rownum++;
-- 查询rownum >5 的所有记录,由于没有输出任何记录,所以rownum并不会自动增长,条件永远不符合,查询出的结果为null
select rownum,emp.* from emp where rownum > 5;
-- 查询rownum <5 的所有记录,此语句正常输出
select rownum,emp.* from emp where rownum < 5; -- 查询员工表中工资最高的前三名的员工信息
select rownum, empno, ename, sal
from (select emp.* from emp order by sal desc) t
where rownum <= 3;
-- 查询员工表中第5-10的记录
-- 先查询前10条记录,查询line >=5 的所有记录
select *
from (select rownum line, emp.* from emp where rownum <= 10) t
where line >= 5;
2、rowid : 伪列, 表示的每行记录在磁盘中存放的物理地址, 主要是运用在索引查询中。
select rowid,emp.* from emp where deptno=20;
当要删除表中重复记录时,可根据指定字段进行分组,查询所有最小rowid,只保留rowid最小的记录,删除掉其他记录即可。
八、集合运算
并集运算: union
应用场景:
数据统计的时候
1997年,公司开发项目记录员工信息
员工编号, 员工姓名, 年龄, 工资, 大哥大
2007年,系统升级,QQ,手机
新的员工表:
员工编号, 员工姓名, 昵称 年龄, 工资,QQ,手机
SQL语句示例:
-- 查询工资大于1500, 或者是20号部门下的员工
select * from emp where sal > 1500 or deptno = 20; -- 并集运算: 去除重复记录
select * from emp where sal > 1500
union
select * from emp where deptno=20; -- 并集运算:不去重
select * from emp where sal > 1500
union all
select * from emp where deptno=20; -- 交集运算
select * from emp where sal > 1500
intersect
select * from emp where deptno=20; -- 差集运算
select * from emp where sal > 1500
minus
select * from emp where deptno=20;
集合运算中的注意事项:
1. 结果集列的数量必须保持一致, 可以使用相同类型或者null补齐
2. 列的类型要保持一致
3. 集合运算的时, 列的含义要相同或者接近
select ename,sal from emp where sal > 1500
union
select ename,sal from emp where deptno=20; select ename,sal from emp where sal > 1500
union
select ename,0 from emp where deptno=20; select ename,sal from emp where sal > 1500
union
select ename,null from emp where deptno=20; -- 错误的演示
select ename,sal from emp where sal > 1500
union
select ename,'没有' from emp where deptno=20; select ename,sal from emp where sal > 1500
union
Oracle数据库基本操作(三) —— DQL相关内容说明及应用的更多相关文章
- Oracle数据库基本操作(一) —— Oracle数据库体系结构介绍、DDL、DCL、DML
一.Oracle数据库介绍 1.基本介绍 Oracle数据库系统是美国ORACLE公司(甲骨文)提供的以分布式数据库为核心的一组软件产品,是目前最流行的客户/服务器(CLIENT/SERVER)或B/ ...
- Java连接Oracle数据库的三种连接方式
背景: 这两天在学习Oracle数据库,这里就总结下自己上课所学的知识,同时记录下来,方便整理当天所学下的知识,也同时方便日后自己查询. SQL语句的话,这里我就不多讲了,感觉和其他的数据库(MySQ ...
- Oracle 数据库基本操作——实用手册、表操作、事务操作、序列
目录: 0. 参考链接与参考手册1. oracle 实用(常用操作)指令2. 数据库基本操作语法 a) 表操作 1)创建表 2)更新表 3)删除表 4)查询 b) 事务操作 c) 序列操作 1)创建序 ...
- Oracle数据库基本操作 (六) —— 数据的导出与导入
一.cmd 下登录oracle数据库下的指定用户 方式一:命令行明文连接登录 打开cmd,输入:sqlplus/nolog 输入:conn username/passworld@数据库实例名 方式二: ...
- Oracle 数据库基本操作——用户管理与文件管理
目录: 1.初始状态 2.登录数据库 3.创建表空间 1)概念 2) 基本表空间 3)表空间管理 4.创建新用户 5.删除用户 6.用户的授权 1)定义 2)授予权限的方法 3)权限分类 4)授权注意 ...
- oracle建表权限问题和JSP连接oracle数据库基本操作
JSP连接oracle数据库相关操作 1.创建表 打开Enterprise Manager Console,为用户添加权限CREATE ANY TABLE和分配一定的表空间USERS限额1024k. ...
- 在不重装系统的情况下撤底删除oracle数据库及oralce的相关软件
先从控制面板删除oracle的相关应用及数据库, 删除系统变量 ORACLE_OEM_CLASSPATH=%JAVA_HOME%\lib\ext\access-bridge-64.jar;%JAVA_ ...
- Oracle数据库安装完成后相关问题的解决
笔者一直以来都是使用公司服务器上的oracle数据库,突然一天公司服务器宕机了,项目无法访问数据库跟着瘫痪了,所以准备在自己的机器上安装一个oracle数据库. 从官网下载安装了oracle 11g后 ...
- Oracle数据库的三种验证机制
关于超级管理员登陆不需要密码因为: 数据库的三种验证机制: 操作系统验证(具有sysdba和sysopera的用户) 密码文件验证(具有sysdba和sysopera的用户) 数据库验证(普通用户) ...
- Oracle数据库基本操作 (五) —— 使用java调用存储过程
一.环境准备 登录Oracle数据库scott账号,利用emp进行操作. 1.创建 proc_getyearsal 存储过程 -- 获取指定员工年薪 create or replace procedu ...
随机推荐
- [ActionScript 3.0] 记录几个ByteArray 十六进制 String等相互转换的方法
/** * 通过hax数据返回ByteArray * @param hax 格式 "AA5A000100FF" */ private function getHax(hax:Str ...
- [总结帖]Web小白的基础恶补帖
1. jQuery实现按钮点击跳转网页 <script src="js/jquery/jQuery-2.2.0.min.js" type="text/javascr ...
- jQuery 获取元素当前位置offset()与position()
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8& ...
- 配置不同站点不同版本PHP
Apache 配置 1.常规手动部署apache方法(不会apache配置的请先移步看下Apache基本手工配置方法),解压fcgid,取其mod_fcgid.so至modules目录 2.打开htt ...
- 51nod1965. 奇怪的式子(min_25筛)
题目链接 http://www.51nod.com/Challenge/Problem.html#!#problemId=1965 题解 需要求的式子显然是个二合一形式,我们将其拆开,分别计算 \(\ ...
- golang (5) http 请求分析
http 分析包分析 fmt.Println("get Content-Type: ", r.Header.Get("Content-Type")) var r ...
- 【编程技术-Shell】AWK使用大全
1. AWK中输出特殊字符 输出单引号 涉及到转义字符,但是在使用普通的方法进行转义时,会遇到下面的问题 正确的方法:'\'',使用单引号将转义字符括起来,然后后面加上单引号 输出其他特殊字符 输出 ...
- SVN linux 服务器端配置
一. SVN 简单介绍 Subversion(SVN) 是一个开源的版本号控制系統, 也就是说 Subversion 管理着随时间改变的数据. 这些数据放置在一个中央资料档案库 (repository ...
- java中Filter过滤器处理中文乱码的方法
注意问题:在学习用selvert的过滤器filter处理中文乱码时,在filter配置初始化时用了utf-8处理中文乱码,而在提交的jsp页面中却用了gbk.虽然两种都可以出来中文乱码,但是却造成了处 ...
- SpringMVC中配置AOP拦截controller 失效
来源:http://www.oschina.net/question/222929_124314 目测大部分同学的aop失效都是因为在springmvc的配置文件里面扫描了类,那么spring去扫描的 ...