Oracle数据库

数据库:根据数据的结构 对数据进行存储,组织和管理的仓库
          可以理解成本地磁盘的一些文件

Oracle是管理数据库的软件

早期数据库存储数据的特点
   一个文件保存的都是学生姓名  一个文件保存的都是教师姓名 一个文件保存的都是课程信息
这就对查询数据造成了很大的麻烦 查找tom是那个班 查找老师教的课程是什么 没有办法找到  
只能查看有没有tom这个学生 有没有数学这门课
但在实际应用中情况并不是这样 数据与数据之间是存在关系的
    例如:查看老师的信息时 可以查询出它教的学生有哪些 教的课是什么
根据数据与数据之间的这种关系 产生了一种新的概念 关系型数据库
  1970年,IBM的研究员,有“关系数据库之父”之称的[埃德加·弗兰克·科德博士在刊物《Communication of the ACM》
 (大型共享数据库的关系模型)”的论文,
  文中首次提出了数据库的关系模型的概念,奠定了关系模型的理论基础。
   埃里森实现

一个关系数据库是由多个表组成的 表示关系型数据库存储数据的基础
在数据库中数据都是以表的形式保存的

表的特点:
    表具有行和列 每一行表示数据表中一条完整的信息
    每一列表示一条记录中都包含那些内容

主流关系型数据库

 Oracle  :oracle公司(中文名叫[甲骨文公司]
 Mysql:开源的 Mysql->Sun->Oracle
 SQL Server:微软
 DB2:IBM

关系型数据库存储数据的特点

 关系型数据库以表的形式保存数据
 数据表具有行和列 
 一行数据 又可以称为一行记录
 每一列表示一行记录 具体又那些信息 列又称为 字段

结构化查询语言:

1.DQL 数据查询语言
2.DML 数据操作语言
3.TPL 事务处理语言
4.DDL 数据定义语言
5.DCL 数据控制语言

数据类型:

1.数值类型
2.字符类型
3.日期类型

select * from emp;

--select 关键字 表示查询
-- * 表示所有的列(字段)
-- from 表示要查询的数据来自于那张表
-- emp 要查询数据的表名
-- select * from table_name

--查询部门表中的所有数据
select * from dept;

--查询薪资等级表中所有的数据
select * from salgrade;

查询表中的具体列

--查询员工表中员工姓名有哪些
select ename from emp;

--查询emp表中部门号有那些
select deptno from emp;

--查询部门信息表中部门名称有那些
select dname from dept;

查询多个列的信息

--查询emp表中员工姓名和薪资
select ename ,sal from emp;

消除记录中的重复数据 DISTINCT

--查询emp表中有几个部门
--DISTINCT 会将列中重复的记录消除掉
--DISTINCT只能跟在SELECT之后
select distinct deptno,sal from emp;

关键字

--关键字 列如SELECT FROM DISTINCT
--在SQL语句中具有特殊的功能
--关键字在SQL语句中 不区分大小写

--查询雇员表中有几种岗位
select distinct job from emp;

--查询薪资上调500后是多少
--sal+500 表达式
select sal,sal+500 from EmP;

--查询薪资上调500后的年薪是多少
select sal,sal+500,(sal+500)*12 from emp;

--查询员工姓名以及他的总收入(年薪+奖金)
select ename,comm,sal*12+comm from emp;

空值NULL

--comm(奖金)列没有任何值的 表示为空 NULL
--NULL 表示没有实际意义的 不存在的内容
--任何包含了NULL 的表达式 其结果都为NULL

列别名

--查询 薪资上调500后的年薪
select (sal+500)*12 from emp;

--查询 薪资上调500后的年 总收入
select (sal+500)*12+comm from emp;

select (sal+500)*12+nvl(comm,0) from emp;

-- 当需要检索的列过长 或者 表示的含义不明确时
-- 适用列别名 进行简洁显示
-- 列/列的表达式 as 列别名
-- 列/列的表达式 列别名

--查询员工的编号 显示成 编号 ,员工薪资 显示成 月薪
select empno as 编号,sal 月薪 from emp;

--列别名特点
--如果列别名的内容区分大小写 需要写在双引号中 ""
--如果列别名中包含空格 需要写在双引号中 ""

select ename ,hiredate "RzRq" from emp;
select sal 薪asdDd资 from emp;
select ename,deptno "部门 编号" from emp;

连接操作符

select ename||job||sal from emp;

--在ORACLE中字符内容用单引号表示 ''
select ename||' is a '||job from emp;

限制条件

--限制数据
--实际就是对检索的数据加上限制条件
--只有符合条件的数据才会显示在结果集中
--不符合条件的数据则不会显示
--语法 WHERE + 限制条件

-- select name ,身高
-- from emp
-- where 身高>180
--身高>180 逻辑表达式/条件表达式
-- 条件表达式 :> , < ,>=, <= ,<> != ,=

--查询部门号为10的员工姓名和薪资
select ename,sal,deptno
from emp
where deptno=10

SQL语句分析方式

-- 需要检索的列有哪些
-- 这些列来自于那张表
-- 是否存在限制条件

-- 查询薪资大于等于1500的员工编号和姓名以及薪资
-- 员工编号 姓名 薪资
-- EMP
-- 薪资大于等于1500
select empno ,ename ,sal
from emp
where sal>=1500;

特殊比较操作符
-- between 数值1 and 数值2
-- 表示某个列的值是否在数值1和数值2之间

select ename ,sal from emp where sal between 1500 and 3000;

--查询入职日期在81年2月22号之后入职的员工有哪些
-- 姓名/*
-- emp
-- 入职日期在81年2月22号之后 hiredate>81年2月22号
select * from emp
where hiredate>'02-4月-81'

--查询员工SMITH的薪资是多少
--检索薪资
--emp
--员工smith的薪资
select sal from emp
where ename='SMITH ';

--数值类型直接进行比较
--日期类型 需要写在单引号中 注意日期类型的数据书写格式 DD-MMM-YY
--字符类型 需要写在单引号中 区分大小写

--查询在81年2月20号 到 81年9月28号期间入职的员工有哪些
-- */ename
-- emp
-- between .. and
select ename ,hiredate
from emp
where hiredate between '20-2月-81' and '28-9月-81';

-- In()
-- 判断要比较的值是否于集合列表中的任意一个数据相同
--集合列表 表示括号中放入的值

select ename,deptno
from emp
where deptno in(10,30);

--查询薪资等于1500 或者等于3000的员工姓名和薪资
-- ename ,sal
--emp
-- sal=1500或者=3000
select ename,sal
from emp
where sal in(3000);

--is null 表示为空
判断要比较的值是不是为空
-- is not null 表示不为空

select ename ,comm 
from emp
where comm is null

select ename ,comm 
from emp
where comm is not null

--查询那些员工没有上级领导
select ename ,mgr
from emp
where mgr is null;

-- LIKE
-- 表示部分匹配
-- % 表示任意个字符 _ 表示一个字符

--查询员工姓名第一个字母是A的有哪些
select ename from emp
where ename like 'A%';

--查询员工姓名中第二个字母是A的有哪些
select ename from emp
where ename like '_A%';

逻辑比较符

-- and
-- 将多个条件表达式进行合并
-- 条件表达式1 and 条件表达式2
-- 只有1和2同时成立 整个结果才成立
-- 只要1和2当中有一个不成立 整个结果则不成立

select ename ,sal
from emp
where sal>=1500
and sal<=3000;

-- 查询部门号为10并且薪资大于1500的员工姓名,薪资,部门号
select ename,sal ,deptno
from emp
where deptno=10
and sal>1500;

--查询部门号为20,薪资大于800并且职位是SALESMAN
--的员工姓名,职位及薪资
select ename,sal,job
from emp
where deptno=30 AND sal>800 AND job='SALESMAN';

-- OR
-- 条件表达式1 OR 条件表达式2
-- 要求1或2中只要有一个成立 则整个结果成立

--查询薪资大于1500或者部门号为10的员工姓名和薪资以及部门
select ename ,sal ,deptno
from emp
where sal > 1500 or deptno=10;

--查询部门号不等于20的员工姓名
select ename from emp
where deptno<>20;

select ename from emp
where deptno!=20;

  • 逻辑运算符 AND 的优先级高于 OR
    -- 可以适用括号改变逻辑表达式的优先级
SELECT ename, job, sal
 FROM   emp
 WHERE  
( job='SALESMAN' OR  job='PRESIDENT') AND    sal>1500;

--排序 order by
-- ASC 表示升序 DESC 降序
--默认就是升序
select ename ,sal
from emp
order by sal desc;

select ename ,mgr,sal
from emp

--多字段排序规则
--先以第一个列进行排序 当第一个列中
--出现重复记录时 再以后面列进行排序
--order by 子句永远写在select语句的最后

章节练习

起列别名时,有三种特殊情况需要加双引号,以下不属于这三种情况之一的选项是( )
A.区分大小写 B.含有特殊字符 C.包含空格 D.包含中文

模糊查询的关键字是( )
A .in B. is null C. like D.between and

.查询在1981年到1982年入职的的员工信息,下列代码中最正确的是( )
A.select * from emp where hiredate between 81 and 82
B.select * from emp where hiredate like ‘%1981’
C.select * from emp where hiredate between ‘01-1月-1981’ and ‘31-12月-1982’
D.select * from emp where substr(hiredate,-4,4) = 1981

以下代码,对于去重关键字DISTINCT的使用正确且有意义的是( )
A. select distinct count(*) from emp
B. select count(distinct deptno) from emp
C.select sal distinct from emp
D. select distinct,empno,ename from emp

查询入职时间在1982-8-10之后,并且职位是SALESMAN的员工姓名、入职时间、职位( )
A. Select ename , hiredate ,job from emp where hiredate > ‘10-8月-82’ and job
=’SALESMAN’;
B. Select ename , hiredate ,job from emp where hiredate > ‘1982-08-10’ and job =’SALESMAN’;
C. Select ename , hiredate ,job from emp where hiredate > ’10-8月-82’ and job<>’SALESMAN’;
D. Select ename , hiredate ,job from emp where hiredate < ‘1982-08-10’ and job <>’SALESMAN’;

查询员工姓名的第1个字母是S的员工姓名( )
A .Select ename from emp where ename like ‘S%’;
B. Select ename from emp where ename like ‘_S%’;
C. Select ename from emp where ename like ‘__S%’;
D. Select ename from emp where ename like ‘/S%’;

查询除了10号部门以外的员工姓名、部门编号( )
A. Select ename , deptno from emp where deptno <>10;
B. Select ename , deptno from emp where deptno =10
C. Select ename , empno from emp where deptno <>10
D. Select ename , deptno from emp where deptno ==10

查询部门号为20号员工的信息,按工资降序排序 ( )
A. Select * from emp where deptno =20 group by sal
B. Select * from emp where deptno =20 order by sal
C. Select * from emp where deptno =20 order by sal desc
D. Select * from emp where deptno =20 group by sal desc

查询没有上级的员工(经理号为空)的员工姓名 ( )
A. Select ename from emp where empno is null
B. Select ename from emp where mgr is null
C. Select ename from emp where mgr is not nul
D. Select ename from emp where empno is not null

查询工资大于等于2000并且部门为10员工的姓名,工资、部门编号( )
A. Select ename ,sal ,deptno from emp where sal>=2000 and deptno=10
B. Select ename ,sal ,deptno from emp where sal>2000 and deptno=10
C. Select ename ,sal ,deptno from emp where sal<=2000 and deptno=10
D. Select ename ,sal ,deptno from emp where sal>=2000 and deptno<>10

关于模糊查询中通配符"_"描述正确的是( )
A. “_”代表多个字符
B. “_”代表一个字符
C .“_”不能与“%”一同使用
D. “_”代表代表零个或多个字符

语句WHERE SAL BETWEEN 800 AND 3500 与下列哪个子句等价( )
A .WHERE SAL>=800 AND SAL<=3500
B .WHERE SAL>800AND SAL<3500
C .WHERE SAL>=800 OR SAL<=3500
D .WHERE SAL>=800AND SAL <3500

下列SQL是什么含义( )
SELECT * FROM emp WHERE deptno =10 OR sal > 2000
A. 查询工资大于2000的员工信息
B. 查询部门号为10或者工资大于2000的员工信息
C. 运行时错误
D. 语法错误

查询公司中有几种工作岗位( )
A. Select distinct job from emp
B. Select job distinct from emp
C. Select job from emp
D. Select distinct ,job from emp

查询公司员工的姓名,月薪,年薪( )
A. Select ename ,sal,sal * 12 from emp ;
B. Select ename ,sal * 12,sal from emp ;
C. Select ename ,sal,sal+sal * 12 from emp ;
D. Select ename ,sal,sal * 6 from emp ;

执行语句:
SELECT address1||’,'||address2||’,'||address2 ”Address” FROM employ;将会返回( )列。
A. 0 B. 1 C. 2 D.3

ORACLE 用来判断列是否为空的操作法是
A.= NULL B.IS NULL C.AS NULL D.null is

如果在where子句中有两个条件要同时满足,应该用以下哪个逻辑符来连接( )
A.OR B.NOT C.AND D.NONE

下列SQL是什么含义:SELECT empno FROM emp WHERE comm=100 or sal>2300
A 返回那些工资的50%大于2300的员工信息
B 运行时错误
C 语法错误
D 返回那些奖金为100或者工资大于2300的员工信息

下面哪个SQL语句可以查询出名字当中有"A%B"这样的员工
A select * from emp where ename like '%A\%B%' escape ' \ ';
B select * from emp where ename like '%A@%B%' escape '@';
C select * from emp where ename like '%A%B%' escape '%';
D select * from emp where ename like '%A@%B%' escape '@';

显示姓名中没有'L'字的员工的详细信息并且含有'SM'字的员工信息

查询职位(JOB)为'PRESIDENT'的员工的工资

单行函数

处理一列数据 返回一个结果

函数中的内容,叫参数
参数的个数可以没有 也可以是多个

函数名([参数,...])

参数的数据类型:数值,字符 ,日期

函数返回的结果可以于参数的类型不一致

函数于函数之间 可以进行嵌套

单行函数的分类

1.字符函数:主要用于处理字符类型数据的

   --字符函数

--LOWER() 将参数转换为全小写
-- 参数的数据类型 字符型 参数个数 1

select ename,lower(ename) from emp
where deptno=10;
--UPPER() 将参数转为全大写
--参数:字符型 个数:1个
select upper(lower(ename)) from emp;

--伪表/虚表 dual
select upper('abcd') from dual;

select * from dual;

--INITCAP() 将参数的首字母转为大写 其它字母变小写
--参数 :字符类型 个数:1个
--特点:如果参数是由多个词组成 则每个词的首字母大写

select initcap(ename) from emp;

select initcap('abcDE') from dual;

select initcap('hi hello') from dual;

--查询所有员工姓名转换为小写后 ,名字中
--包含a的有哪些
select lower(ename)
from emp
where lower(ename) like '%a%';

--concat( ) 与 || 等价 连接函数
--参数:字符类型 个数:2个
select ename||job from emp;

select concat(concat(ename,job),ename) from emp;

--SUBSTR() 截取字符串
--参数类型 : 字符 数值 数值 个数:3个
--参数1 :表示原字符串 ,参数2:从第几位开始截取
--参数3:表示截取的长度 默认不写 表示从起始位开始全部截取
select ename,substr(ename,2) from emp;

--查询员工姓名中第三个字母是A的有哪些
select ename from emp
where substr(ename,3,1)='A';

--LENGTH() 返回参数的长度
--参数:字符 个数:1个 返回结果:数值
select ename,length(ename) from emp;

--查询员工姓名长度为5的有那些

select ename ,length(ename)
from emp
where length(ename)=5;

--INSTR() 返回子串在原字符串中的位置
--参数:字符 字符 数值 数值 个数:4个
--参数1:原字符串
--参数2:子串
--参数3:从原字符串中第几位开始查找
--参数4:子串第几次出现
--如果子串在原字符串中不存在 则返回结果是0

select ename ,instr(ename,'MI',2,1) from emp;

select instr('Tinking in Java','itn',1,1) from dual;

--LPAD() 左填充
select ename,lpad(ename,3,'m') from emp;
-- 参数类型:字符 数值
--个数 :3个
--参数1 :表示原字符串
--参数2:表示填充后的字符串长度
--参数3:表示填充的字符
--当参数2的值小于原字符串长度时 会对原字符串进行截取

--RPAD() 右填充
select ename,rpad(ename,3,'*') from emp;

--REPLACE() 替换字符串
select ename,replace(ename,'AL','*') from emp;
--参数类型:字符类型
--参数个数:3个
--参数1:表示原字符串
--参数2:表示需要替换的子串
--参数3:替换后的内容
--如果参数3不写 返回的结果会将参数2消除掉

-- TRIM() 消除字符
-- trim(参数1 FROM 参数2)
--参数类型:字符类型 个数:2个
--将参数2两端的参数1消除掉

select ename ,trim('S' from ename ) from emp;

select trim('a' from 'aabca') from dual;

select trim('a' from 'ababaca') from dual;

select trim('a' from 'bca') from dual;

2.数值函数:对数值类型的数据进行操作

--ROUND() 四舍五入
--参数类型 :数值类型 个数:2个
--参数1:表示需要进行舍入数值
--参数2:表示舍入到小数点后几位

select round(100.57,0) from dual;

--TRUNC() 截取到小数点后N位

select trunc(125.45,-2) from dual;

--MOD() 取余

select mod(5,2),mod(5,-2),mod(-5,2),mod(-5,-2) from dual;

select mod(sal,comm) from emp;

3.日期函数

--日期+数值 表示加上相应的天数
select hiredate,hiredate+1 from emp;

select to_date('10-4月-17','DD-MON-RR') - TO_date('4-4月-17','DD-MON-RR') from dual;

--SYSDATE 当前系统时间
select sysdate from dual;

--MONTHS_BETWEEN() 返回两个日期数据之间相隔的月数
--参数类型:日期类型
--参数个数:2个
--大的在前 小的在后

select trunc(months_between(sysdate,hiredate)) from emp;

--ADD_MONTHS() 加上相应的月份
--参数类型:日期 数值、
--参数1 表示日期类型的数据
--参数2 表示加上几个月

select add_months(sysdate,1) from dual;

select add_months(sysdate,10) from dual;

--NEXT_DAY() 返回当前日期 下一个指定星期是那一天

select next_day(sysdate,'星期一') from dual;

select next_day(sysdate,2) from dual;

--LAST_DAY() 返回指定日期当月的最后一天
select last_day(sysdate) from dual;

SELECT NEXT_DAY('02-2月-06','星期一') NEXT_DAY
FROM DUAL;

SELECT empno, hiredate,
ROUND(hiredate, 'MONTH')
FROM emp

WHERE SUBSTR(hiredate,-2,2)='81';

select round(to_date('15-2月-17','DD-MON-YY'),'MONTH') FROM DUAL;

SELECT EXTRACT(day FROM SYSDATE) from dual;

--1.查询服务器当前时间
select sysdate from dual;
--2.查询部门10,20的员工截止到2000年1月1日,工作了多少个月,
--入职的月份。(提示:使用months_between,extract)
select extract(month from hiredate),months_between('1-1月-00',hiredate)
from emp
where deptno in(10,20);

--3.如果员工试用期6个月,查询职位不是MANAGER的员工姓名,
--入职日期,转正日期,入职日期后的第一个星期一,
--入职当月的最后一天日期。(提示:使用add_months,next_day,last_day)
select ename,hiredate,add_months(hiredate,6),next_day(hiredate,'星期一'),
last_day(hiredate)
from emp
where job<>'MANAGER';

4.转换函数

4.通用函数
-to_char()
--将入职日期以'DD Month YYYY'显示
select hiredate ,to_char(hiredate,'DD/MM/YYYY')
from emp;

--将入职日期显示成xxxx年xx月xx日的格式
select hiredate,to_char(hiredate,'YYYY"年"MM"月"DD"日"')
from emp;

--将入职日期显示成xxxx-xx-xx的格式
select hiredate,to_char(hiredate,'YYYY-MM-DD')
from emp;

select sal ,to_char(sal,'L09,999.99') from emp;

select sal,to_char(sal,'L99') from emp;

--2月 MON
--2 MM
select to_date('9-2月-81','DD-MM-YY') FROM DUAL;

--1.显示服务器系统当前时间,格式为2007-10-12 17:11:11(提示:使用to_char函数)
select to_char(sysdate,'YYYY-MM-DD HH24:MI:SS')
FROM dual;

--2.显示ename、hiredate 和 雇员开始工作日是星期几,列标签DAY(提示:使用to_char函数)
select ename,hiredate ,to_char(hiredate,'DAY') DAY
FROM emp;

--3.查询员工姓名,工资,格式化的工资(¥999,999.99) (提示:使用to_char函数)
select ename,sal ,to_char(sal,'L999,999.99') from emp;

--4.把字符串2015-3月-18 13:13:13 转换成日期格式,
--并计算和系统当前时间间隔多少天。 (提示:使用to_date函数)
select to_date('2015-3月-18 13:13:13', 'YYYY-MON-DD HH24:MI:SS'),
SYSDATE - to_date('2015-3月-18 13:13:13', 'YYYY-MON-DD HH24:MI:SS')
FROM DUAL;
--nvl(comm,0) 如果comm为null 用0替换
--要求参数的数据类型保持一致
select ename ,nvl(to_char(comm),'abc')
from emp;

--NVL2(e1,e2,e3)
--如果e1不是NULL 返回e2 否则返回e3

select comm,nvl2(comm,comm,0) from emp;

--NULLIF(E1,E2) 比较e1和e2
--如果e1与e2相等 返回 NULL
--如果e1与e2不相等 返回e1

select nullif(sal,1500) from emp;

select comm, coalesce(comm,null,0) from emp;

select ename,job,
(case job
when 'CLERK' then '员工'
when 'SALESMAN' then '销售'
when 'MANAGER' then '经理'
end) 部门
from emp;

select job from emp;

select ename,deptno,
decode(deptno,
10 , '销售部',
20 ,'技术部',
30 , '管理部'

) 部门
from emp;

--1.计算2000年1月1日到现在有多少月,多少周(四舍五入)。
select months_between(sysdate,'1-1月-00'),round((sysdate-to_date('1-1月-00','DD-MON-YY'))/7)
FROM DUAL;

--2.查询员工ENAME的第三个字母是A的员工的信息(使用2个函数)。

--3.使用trim函数将字符串‘hello’、‘ Hello ’、‘bllb’、‘ hello
--’分别处理得到下列字符串ello、Hello、ll、hello。
select trim('h' from 'hello') from dual;

--4.将员工工资按如下格式显示:123,234.00 RMB 。
select to_char(sal,'999,999.99')||'RMB'
from emp;

--5.查询员工的姓名及其经理编号,要求对于没有经理的显示“No Manager”字符串。
select ename,nvl(to_char(mgr),'No Manager') from emp;

--6.将员工的参加工作日期按如下格式显示:月份/年份。
--hiredate date to_char()
--将2017-2月-12号显示成 月份/年份 '2017-2月-12' to_date()
select to_char(hiredate,'MON/YYYY') FROM emp;

--7.在员工表中查询出员工的工资,并计算应交税款:
--如果工资小于1000,税率为0,如果工资大于等于1000并小于2000,
--税率为10%,如果工资大于等于2000并小于3000,税率为15%,
--如果工资大于等于3000,税率为20%。
-- sal<1000 sal/1000=0... trunc(sal/1000)=0
--sal>=1000 and sal<2000 trunc(sal/1000)=1
--sal<=2000 and sal >3000
--sal>=3000
select ename,sal ,
decode(trunc(sal/1000),
0 ,0,
1 ,sal * 0.1,
2 ,sal * 0.15,
sal * 0.2
) 税款
from emp;

select sal from emp
order by sal;

--8.创建一个查询显示所有雇员的 ename和 sal。格式化sal为 15 个字符长度,用 $ 左填充,列标签 SALARY。

SELECT HIREDATE,substr(hiredate,4,4) FROM EMP;

select sysdate - to_date('1982-09-08') from emp

--找出每个月倒数第一天受雇的所有员工
select ename,hiredate
from emp
where hiredate=last_day(hiredate);

找出在(任何年份) 2 月入职的所有员工
select ename ,hiredate
from emp
where extract(month from hiredate)=2;

select ename,hiredate
from emp
where to_char(hiredate,'MM')=2;

将所有的雇员姓名按照小写字母显示
select lower(ename) from emp;

要求查询出姓名长度正好是5的雇员信息
select * from emp
where length(ename)=5;

使用字符“”替换掉姓名中的所有字母“A”
select replace(ename,'A','
') FROM EMP;

要求截取每个雇员姓名的后三个字母
SELECT ENAME,substr(ename,-3,3) from emp;

求出每个雇员到今天为止的雇佣天数
select sysdate - hiredate from emp;

求出每个雇员到今天为止的雇佣月份
select ename,months_between(sysdate,hiredate) from emp;

把hiredate列看做是员工的生日,求本月过生日的员工
select ename ,hiredate
from emp
where to_char(hireDAte,'MM')=TO_CHAR(sysdate,'MM');

求1982年入职的员工
SELECT ename,hiredate
from emp
where to_char(hiredate,'YYYY')='1982';

显示所有员工的姓名的前三个字符
select ename,substr(ename,1,3) from emp;

章节练习

下列与sql语句 Select * from emp where substr(ename,4,1) = ‘s’
等效的语句是( )
A.SELECT * FROM emp WHERE instr(ename,’s’1,4) = 4
B.SELECT * FROM emp WHERE ename like ‘___s’
C.SELECT * FROM emp WHERE extract(‘s’ from ename) = 4
D.SELECT * FROM emp WHERE instr(ename,’s’,4,1) = 4

查询在1982年入职的的员工信息,下列代码中正确的是( )
A.select * from emp where hiredate < 1982
B.select * from emp where hiredate like ‘%1982’
C.select * from emp where hiredate between ‘01-1月-1981’ and ‘31-12月-19’
D.select * from emp where to_char(hiredate,’YYYY’) = ‘1982’

下列哪个SQL语句是错误的( )
A.select * from emp where to_char(hiredate,’YYYY’) = ‘1981’
B.select * from emp where sal > 6000 and substr(ename,4,1) = ‘A’
C.select * from emp where hiredate > ’01-1月-1981’
D.select * from emp where ename like ‘S%’and comm = null

下述针对substr使用及描述正确的是( )
A.substr参数中包含4个参数
B.substr(‘abcdefg’,3,2)的结果是cd
C.select * from emp where substr(ename,2,1) = ‘AB’
D.select * from emp where substr(hiredate,4,4) = ‘1981'

查询语句SELECT ROUND(13.57),ROUND(13.57,1),ROUND(13.57,-1),TRUNC(13.57,-2) FROM DUAL 返回结果,正确的是( )
A .13.57,13.6,10,13
B .13,13.5,14,0
C.14,13.6,10,0
D.13.6,13.5,11,13

下列哪个SQL语句能正确执行( )
A.select sysdate - to_date(‘1982-09-08’) from emp
B.select ename || job || sal + 500 from emp
C.select hiredate,’01-1月-2017’-hiredate from emp
D.select hiredate,to_date(‘1985年11月11日’,’YYYY”年”MM”月”DD”日”’) from emp

下述针对substr使用及描述正确的是( )
A.substr参数中包含4个参数
B.substr(‘abcdefg’,3,2)的结果是cd
C.select * from emp where substr(ename,2,1) = ‘AB’
D.select * from emp where substr(hiredate,4,4) = ‘1981’

ROUND 和TRUNC 操作的区别是( )
A. ROUND在截掉数据时有四舍五入的判断,TRUNC直接按要求截掉没有进位。
B. 都是将数据按指定的长度截断
C. TRUNC是四舍五入,ROUND是截断
D. 都会四舍五入

找出每个月倒数第一天受雇的所有员工

找出在(任何年份) 2 月入职的所有员工

将所有的雇员姓名按照小写字母显示

要求查询出姓名长度正好是5的雇员信息

使用字符“_”替换掉姓名中的所有字母“A”

要求截取每个雇员姓名的后三个字母

求出每个雇员到今天为止的雇佣天数

求出每个雇员到今天为止的雇佣月份

把hiredate列看做是员工的生日,求本月过生日的员工

求1982年入职的员工

显示所有员工的姓名的前三个字符

多表连接

-多表连接
--查询员工姓名,薪资,部门地点
-- 查询的列有那些
-- 这些列来自那张表
-- 有没有限制条件
select ename,sal,loc
from emp ,dept
--笛卡尔积 :一张表中的所有数据与另一张表的所有数据 都进行连接

select * from dept;

--多表连接时 需要加上限制条件 消除笛卡尔积的效果

--等值连接
--查询员工姓名,薪资,部门地点
--emp.deptno=dept.deptno emp表与dept表的关联条件
--deptno 由于deptno同时存在于两张表
--如果直接使用会 产生 未明确定义列的问题
--需要表名进行区分
select ename,sal,loc
from emp,dept
where emp.deptno=dept.deptno;

--查询员工编号,职位,工作地点,部门号,部门名称

select empno,job,loc,dept.deptno,dname
from emp,dept
where emp.deptno=dept.deptno;

--非等值连接
--表与表之间的关联条件不是直接相等的
select ename,sal ,grade
from emp,salgrade
where sal between losal and hisal;

--外连接
--查询所有员工姓名和部门号,没有员工的部门也要显示
--(+) 外连接符号
--如果需要将一些不满足连接条件的数据显示在结果集
--可以使用(+)
--(+)写在那个表中 就会对应出现万能行
--万能行的作用就是与不满足条件的数据进行连接
select ename,dept.deptno
from emp,dept
where emp.deptno(+)=dept.deptno;

--查询员工姓名,薪资,工作地点,薪资等级 要求薪资大于1500
--多表连接后 如果有其它限制条件 在WHERE中 通过 AND 连接
select ename,sal,loc,grade
from emp,dept,salgrade
where emp.deptno=dept.deptno and sal between losal and hisal
and sal>1500;

--通过表前缀可以提高查询性能

--表别名 代替表名
--当给表起了表别名之后 不能使用表名作为列的前缀
select ename,e.deptno,dname
from emp e ,dept d
where e.deptno=d.deptno;

--N个表 表的关联条件至少 N-1

--1.写一个查询,显示所有员工姓名,部门编号,部门名称。
select ename,e.deptno,dname
from emp e,dept d
where e.deptno=d.deptno;

--2.写一个查询,显示所有工作在CHICAGO并且奖金不为空的员工姓名,工作地点,奖金
select ename, loc, comm
from emp e, dept d
where e.deptno = d.deptno
and loc = 'CHICAGO'
and comm is not null;

--3.写一个查询,显示所有姓名中含有A字符的员工姓名,工作地点。
select ename,loc
from emp e,dept d
where e.deptno=d.deptno
and ename like '%A%';

1.查询每个员工的编号,姓名,工资,工资等级,所在工作城市,按照工资等级进行升序排序。
select empno,ename,sal,grade,loc
from emp e,dept d,salgrade s
where e.deptno=d.deptno and e.sal between losal and hisal
order by grade ;

--自连接
--查询每个员工的姓名和直接上级姓名
--e 表示员工表 l 表示领导表
--关联条件 员工表的领导编号=领导表员工编号
select e.ename,l.ename
from emp e,emp l
where e.mgr=l.empno

--查询员工姓名,薪资,领导姓名 ,领导薪资
--要求员工薪资大于1500
select e.ename,e.sal ,l.ename,l.sal
from emp e,emp l
where e.mgr=l.empno
and e.sal>1500;

--1.查询所有工作在NEW YORK和CHICAGO的员工姓名,员工编号,以及他们的经理姓名,经理编号。
select e.ename,e.empno,l.ename,l.empno
from emp e,emp l ,dept d
where e.mgr=l.empno and e.deptno=d.deptno
and d.loc in('NEW YORK','CHICAGO');

--2.第上一题的基础上,添加没有经理的员工King,并按照员工编号排序。
select e.ename,e.empno,l.ename,l.empno
from emp e,emp l
where e.mgr=l.empno(+);

--3.查询所有员工编号,姓名,部门名称,包括没有部门的员工也要显示出来。
select empno,ename,dname
from emp e,dept d
where e.deptno=d.deptno(+);
--查询每个员工的 姓名,工资,工资等级,所在工作城市

select ename,sal,grade,loc
from emp e,salgrade s,dept d
where e.sal between s.losal and s.hisal
and e.deptno=d.deptno;

--列出所有员工的姓名以及其直接上级的姓名
select e.ename,l.ename
from emp e,emp l
where e.mgr=l.empno(+);

--查询所有工作在NEW YORK和CHICAGO的员工姓名,员工编号
select e.ename,e.empno
from emp e,dept d
where e.deptno=d.deptno
and d.loc in ('NEW YORK','CHICAGO');

--查询所有工作在NEW YORK和CHICAGO的员工姓名,员工编号,以及他们的经理姓名,经理编号
select e.ename,e.empno,l.ename,l.empno
from emp e,emp l ,dept d
where e.mgr=l.empno(+)
and e.deptno=d.deptno
and loc in('NEW YORK','CHICAGO');

--显示工作在CHICAGO的员工姓名,部门名称,工作地点
select ename,dname,loc
from emp e ,dept d
where e.deptno=d.deptno
and loc='CHICAGO';

--显示入职日期在81年2月1日之后的员工姓名,部门名称,入职日期
select e.ename,e.hiredate,d.dname
from emp e,dept d
where e.deptno=d.deptno
and hiredate>'1-2月-81';

--显示员工JONSE的部门名称,直接上级名称
select e.ename,d.dname,l.ename
from emp e,emp l,dept d
where e.mgr=l.empno
and e.ename='JONES'
and e.deptno=d.deptno;

--列出受雇日期早于其直接上级的所有员工的编号,姓名,部门名称
select e.empno ,e.ename,d.dname
from emp e,emp l,dept d
where e.mgr=l.empno
and e.deptno=d.deptno
and e.hiredate

--列出部门名称和这些部门的员工姓名,部门号
select dname,ename,e.deptno
from emp e,dept d
where e.deptno(+)=d.deptno;

--交叉连接

select ename,sal,dname
from emp e cross join dept d;

select ename,sal,dname
from emp e,dept d;

--自然连接
select ename,sal,grade
from emp e natural join dept d;

select ename,sal,dname
from emp e,dept d
where e.deptno=d.deptno;

-USING
select ename,sal,dname
from emp e JOIN dept d USING(deptno);

--ON
--其它的限制条件建议写在WHERE子句中
--使SQL语句的结构更加清晰
select ename,sal,dname
from emp e join dept d
on e.deptno=d.deptno
and sal>1500;

select ename,sal ,dname,grade
from emp e join dept d
on e.deptno = d.deptno
join salgrade s
on e.sal between s.losal and s.hisal;

--左外连接 LEFT [outer] JOIN
-- 在LEFT [outer] JOIN 左边的表 作为主表(基表)
-- 主表中不满足连接条件的数据也会显示
--查询员工姓名和直接领导姓名,没有领导员工也要显示
select e.ename,l.ename
from emp e,emp l
where e.mgr=l.empno(+);

select e.ename,l.ename
from emp e left join emp l
on e.mgr=l.empno;

--右外连接 RIGHT [OUTER] JOIN
--在 RIGHT [OUTER] JOIN 右边的表 作为主表
--主表中不满足连接条件的数据也会显示

--查询员工姓名 ,部门名称,部门编号 没有员工的部门也要显示
select e.ename,d.dname,d.deptno
from emp e,dept d
where e.deptno(+)=d.deptno;

select e.ename,d.dname,d.deptno
from emp e right join dept d
on e.deptno = d.deptno;

--全外连接 FULL [OUTER] JOIN

SELECT e.ename,l.ename,e.deptno
from emp e full join emp l
on e.mgr=l.empno;

分组函数

--MAX() MIN() SUM() AVG() COUNT()
--MAX() 求一组数据的最大值
--MIN() 求一组数据的最小值
MIN和MAX可以用于任何数据类型

--SUM() 求一组数据的和
--AVG() 求一组数据的平均值
SUM和AVG函数都是只能够对数值类型的列或表达式操作

--COUNT() 统计数 / 记录数
除了COUNT(*)之外,其它所有分组函数都会忽略列中的空值,然后再进行计算

--查询emp表中的薪资的最大值和最小值
--最高薪资 最低薪资

select max(sal),min(sal) from emp;

--ename返回一列数据 而max(sal),min(sal) 返回单个数据
--它们之间是多对一的关系 没有办法匹配显示
select ename, max(sal),min(sal) from emp
where ename='SMITH';
--7369 SMITH CLERK 7902 1980/12/17 800 20

--求所有员工薪资和
select sum(sal) from emp;

--求所有员工平均薪资
select avg(sal) from emp;

--查询有多少部门
select distinct deptno from emp;

select count(distinct deptno) from emp;

--查询10号和20部门的最高薪资
select max(sal) from emp
where deptno in(10,20);

--group by 分组
--需要分组的列 写group by之后 多个列之间用逗号隔开

--查询每个部门的最高薪资,最低薪资
select deptno,max(sal),min(sal)
from emp
group by deptno;

--查询10号和20部门的最高薪资
--group by 要写在WHERE子句之后
select deptno,max(sal),min(sal)
from emp
where deptno in(10,20)
group by deptno;

--查询每个工作岗位的最高薪资最低薪资
select job,max(sal),min(sal)
from emp
group by job;

--查询每个部门的人数
select deptno,count(ename)
from emp
group by deptno;

--查询每个职位的人数 要求薪资大于1500
select job,count(empno)
from emp
where sal >1500
group by job;

-- 查询每个职位的人数,职位,薪资 要求薪资大于1500
-- 在分组语句中 出现在SELECT子句中的列 必须写在GROUP BY
--写在分组函数中的列除外

-- 相反出现在GROUP BY 中的列 ,可以不写在SELECT子句中
select job,sal,count(empno)
from emp
where sal >1500
group by job,sal
order by job;

--max() min
--可用于 数值,日期
--字符类型可以可用 但无意义
select max(hiredate) ,min(hiredate) from emp;

select max(ename) ,min(ename) from emp;

--sum()
--只能处理数值类型的参数
select sum(ename) from emp;

--avg()
--只能处理数值类型的参数
select avg(ename) from emp;

--查询部门号,平均薪资
--要求平均薪资大于1500
--在WHERE子句中不能使用 分组函数
-- having 如果需要使用分组函数作为限制条件
-- 需要写在Having 中

--建议将having写在group by 之后
select deptno ,avg(sal)
from emp
group by deptno
having AVG(sal)>2000;

---语法格式有误
select ename,sal
from emp
having ename like '%A%';

--count() 返回非空记录
select count(mgr) from emp;

--返回记录数(表中数据量)
select count(*) from emp;

select * from emp;

select avg(nvl(comm,0)) from emp;

--SQL语句的执行顺序
--1. from
--2. where
--3. group by
--4. having
--5. select
--6. order by

--由于SQL语句的执行顺序不同
--where中使用列别名时 select语句还未执行
--所以无法使用

章节练习

--1.查询部门20的员工,每个月的工资总和及平均工资。
--sum(sal) avg(sal)
-- emp
-- deptno=20
select sum(sal),avg(sal)
from emp
where deptno=20

--2.查询工作在CHICAGO的员工人数,最高工资及最低工资。
select count(*) ,max(sal),min(sal)
from emp e ,dept d
where e.deptno=d.deptno
and d.loc='CHICAGO';

--3.查询员工表中一共有几种岗位类型。
SELECT COUNT(mgr) from emp;

select avg(nvl(comm,0)) from emp

select sum(comm) from emp;

--1.查询每个部门的部门编号,部门名称,部门人数,
--最高工资,最低工资,工资总和,平均工资。
select e.deptno,dname,count(empno),max(sal),min(sal),sum(sal),avg(sal)
from emp e,dept d
where e.deptno=d.deptno
group by e.deptno,dname;

--2.查询每个部门,每个岗位的部门编号,部门名称,
--岗位名称,部门人数,最高工资,最低工资,工资总和,平均工资。
select e.deptno,dname,job,count(ename),max(sal),min(sal),sum(sal),avg(sal)
from emp e,dept d
where e.deptno=d.deptno
group by e.deptno,job,dname;

--3.查询每个经理所管理的人数,经理编号,经理姓名,要求包括没有经理的人员信息
select count(e.empno),e.mgr,l.ename
from emp e,emp l
where e.mgr=l.empno(+)
group by e.mgr,l.ename;

--1.查询部门人数大于2的部门编号,部门名称,部门人数。
select e.deptno,dname,count(empno)
from emp e,dept d
where e.deptno=d.deptno
group by e.deptno ,dname
having count(empno)>2;

--2.查询部门平均工资大于2000,且人数大于2的部门编号,
--部门名称,部门人数,部门平均工资,并按照部门人数升序排序。

select e.deptno,dname,count(ename) counts,avg(sal)
from emp e,dept d
where e.deptno=d.deptno
group by e.deptno,dname
having avg(sal)>2000
and count(ename)>2
order by counts;

--1.查询部门平均工资在2500元以上的部门名称及平均工资。
select dname,avg(sal)
from emp e,dept d
where e.deptno=d.deptno
group by e.deptno,dname
having avg(sal)>2500;

--2.查询员工岗位中不是以“SA”开头并且平均工资在2500元以上的岗位及平均工资,
--并按平均工资降序排序。
select job,avg(sal)
from emp e
where job not like 'SA%'
group by job
having avg(sal)>2500
order by avg(sal) desc;

select job,avg(sal)
from emp e
group by job
having avg(sal)>2500
and job not like 'SA%'
order by avg(sal) desc;

--3.查询部门人数在2人以上的部门名称、最低工资、最高工资,
--并对求得的工资进行四舍五入到整数位。
select dname,round(max(sal)),round(min(sal))
from emp e,dept d
where e.deptno=d.deptno
group by e.deptno ,dname
having count(empno)>2;

--4.查询岗位不为SALESMAN,工资和大于等于2500的岗位及每种岗位的工资和。
select job,sum(sal)
from emp
where job <>'SALESMAN'
group by job
having sum(sal)>=2500;

select job,sum(sal)
from emp
group by job
having sum(sal)>=2500
and  job <>'SALESMAN';

--5.显示经理号码和经理姓名,这个经理所管理员工的最低工资,
--没有经理的KING也要显示,不包括最低工资小于3000的,按最低工资由高到低排序。

--6.写一个查询,显示每个部门最高工资和最低工资的差额

你可能感兴趣的:(Oracle数据库)