Oracle学习笔记

Oracle学习笔记

引言

创建文件:可以使数据持久化,但是不区分数据类型,运行效率低
java:有数据类型,在内存中保存数据,但是数据不能持久化
数据库:可以持久化保存数据,具备数据类型,运行效率高

Sql

结构化查询语句

1.简单查询

  • sql的基本结构
select 想查询的字段名 from
  • 查询全部列

需求:查询employees表中的所有内容

select * from employees
  • 给查询结果起别名
select 字段名 (as) 别名,字段名 别名......
--需求:查询员工表中所有员工的工号、名字、工资,展示效果为工号、名字、工资
select employee_id as 工号,first_name 姓名,salary 工资
from employees
  • 字符串拼接
--需求:查询员工表,工号,姓名,工资
select first_name||'.'||last_name 姓名,first_name,last_name
from employees
  • 给查询结果做算术运算
--需求:查询员工的工号、名字、年薪
select employee_id,first_name,salary*13
from employees

2.去重

关键字:distinct
语法结构:select distinct 字段名,字段名...from 表
作用:将查询结果中一行完全相同的记录剔除

--需求:查询所有是领导的工作人员的id
select distinct manager_id from employees

3.排序

关键字:order by 字段名 asc(升序)|desc(降序)
语法结构:select 字段1,字段2,...from 表 order by 字段 asc,字段2 desc

--需求:查询员工ID,first_name,salary,根据salary降序排序
select employee_id,first_name,salary
from employees
order by salary desc

--需求:查询员工ID,first_name,salary,根据salary降序排序,当工资相同时要按照员工id降序排序
select employee_id,first_name,salary
from employees
order by salary desc,employee_id desc

注意:order by 之后可以写多个排序规则,但是只有当第一个排序规则失效时,第二排序规则才有作用,只有当第一个和第二个排序规则都失效时,第三个才有用

4.条件查询

关键字:where 查询条件
语法结构:select...from...where 查询条件

  • 等值查询
-- 需求:查询工资等于17000的员工的id,名字,工资
select employee_id,first_name,salary
from employees
where salary = 17000
  • 不等值查询
-- 需求:查询工资大于17000的员工的id,名字工资
select employee_id,first_name,salary
from employees
where salary > 17000

注意:在where后可以跟任何查询条件,并不是非要使用字段

select employee_id,first_name,salary
from employees
where 1=1  ----  结果为所有数据全部展示

  • 多条件查询
    关键字:and(两者都要成立)| or(两者成立其一即可)
-- 需求:查询工资大于10000并且小于24000的员工信息
select employee_id,first_name,salary
from employees
where salary>10000  and salary<24000

-- 需求:查询在90号部门或者在100部门的员工信息
select employee_id,first_name,salary
from employees
where department_id = 90 or department_id = 100
  • 区间查询:多条件查询的优化
    关键字:between...and...
    语法结构:where 字段 between 条件一 and 条件二(闭区间)
    作用:字段的值在条件一与条件二之间
-- 需求:查询工资大于等于10000并且小于等于24000的员工信息
select employee_id,first_name,salary
from employees
where salary between 10000 and 24000
  • 枚举查询:对多条件查询的优化
    关键字:in(?,?,?)
    语法结构:where 字段 in (条件一,条件二...)
    作用:字段值等于条件一或等于条件二
--需求:查询在90号部门或者在100部门的员工信息
select employee_id,first_name,salary
from employees
where department_id in (90,100)
  • 模糊查询
    关键字:like '模糊匹配字符串'
    • 模糊匹配字符串
      ‘_’:一个下划线,代表在此处有一个任意字符
-- 查询以'S'开头,并且名字长度为6的员工
'S_____'
select * 
from employees
where first_name like 'S_____'
	   '%':一个百分号,代表在此处有0-n个任意字符
'S%' --->以S开头,后面有几个都行
Svn √          Sabclmasbfasbdm √                S √  
'%k'  --->以k结尾
dasdasdk √          k√
'%a%' --->含a就行,a能开头也能结尾
bac √        ac√            gdfgdfgdfgdfga √
-- 查询名字中有k的员工
select * 
from employees
where first_name like '%k%'
  • 空值查询
    关键字:is [not] null
    语法结构:where 字段 is null
    作用:查询该字段为空的信息
-- 查询没有提成的员工信息
select * 
from employees
where commission_pct is null

5.特殊关键字

  • sysdate:显示当前系统时间,当做一个字段来用
-- 查询当前时间
select sysdate from employees
  • systimetamp:时间戳,当做一个字段来用,比sysdate更加精确
select systimetamp from employees
  • dual:哑表,虚表,一行一列
    dual从数据意义上来看,没有任何作用
    作用:为了维护sql语句语法的完整性
select sysdate from dual

函数

可以解决一个特定问题的sql语言

1.单行函数

表中任意一条数据都能得出一个结果

  • length(字段/‘字符串’):字符串的长度
-- 查询‘fafafaf’的长度
select length('fafafaf') from dual
  • to_date(‘字符串类型的日期’,‘日期的格式’):将一个字符串类型的日期,变为日期类型的日期
select to_date('2020-09-25','yyyy-mm-dd') from dual
yyyy
mm
dd
hh24
mi
ss
星期 day
  • to_char(日期类型的日期,‘日期类型的格式’) : 将日期类型转化为字符串类型

2.组函数

需要表中的多条数据,经过分析,给出一个结果
常用组函数

  • count(字段) 统计有效行数
  • min(字段) 最小值
  • max(字段)最大值
  • avg (字段)平均值
  • sum (字段)求和
--求工资最高的工资为多少
select max(salary),min(salary),avg(salary)
from employees


-- 求公司员工总人数
select count(employee_id)
from employees

select count(*)
from employees

-- 求有提成的人的数量
select count(commission_pct)
from employees
where commission_pct is not null

注意:

  • 1.目前若select后添加了组函数,那么在select之后,就只能写组函数,不能写字段名
  • 2.在where后不能直接写组函数
  • 3.对null不做统计

分组

关键字:group by 字段
作用:将表中的数据根据对应字段进行分组
语法顺序:select...from...where...group by...order by
执行顺序:from...where...group by ...select...order by
注意:如果sql进行了分组,在select后可以写分组依据字段

--需求:统计员工表中每个部门的人数
select count(*),department_id
from employees
group by department_id

--需求:统计每个部门的平均工资
select department_id,avg(salary)
from employees
group by department_id

--需求:求每个部门的工资总数

select department_id,sum(salary)
from employees
group by department_id

--需求:求出平均工资大于9000的部门的平均工资
---1.求出所有部门平均工资
select avg(salary),department_id
from employees
group by department_id
---2.做条件查询   avg(salary)>9000
select avg(salary),department_id
from employees
where  avg(salary)>9000
group by department_id    错误 ×××××××××××××××××××××××××××××

having

作用:分组之后的条件过滤
语法:select...from...where...group by...having...order by
指定顺序:from...where...group...having...select...order by

--需求:求出平均工资大于9000的部门的平均工资
--1,求每个部门的平均工资
select avg(salary),department_id
from employees
group by department_id
having avg(salary)>9000

-- 需求:求70,80,90部门的人数
--1.求每个部门的人数
--2.在做过滤(having)  department_id in(70,80,90)
select department_id,count(*)
from employees
group by department_id
having department_id in (70,80,90)

--1.将70,80,90部门的人过滤出来
--2,将过滤后的人进行分组
select count(*),department_id
from employees
where deparment_id in (70,80,90)
group by department_id

伪列

在建表时不用主动声明有此一列,但是建表完成Oracle数据库会自动添加的一列
特点:不声明查询此列时不会自动显示

  • rowid:储存了一条数据在电脑硬盘中的保存位置
select e.*,rowid
from employees e
  • rownum

作用:给查询结果进行排序,从1开始,依次加1,每次查询,都重新排序,只给符合查询结果的数据进行排序(rownum只能小于某个数,rownum不能大于某个数)

--查询:员工表中的前十个人
select employee_id,first_name,salary,rownum
from employees e
where rownum <=10


--查询:员工表中的第11~20人
select employee_id,first_name,salary,rownum
from employees e
where rownum >=11 and rownum<=20      错××××××××××××××××××××××××××××

--查询:工资最高的前十个人
select employee_id,first_name,salary,rownum
from employees 
where rownum<=10
order by salary desc                 错XXXXXXXXXXXXXXXXXXXXXXXXXX
问题:先进行where判断,再进行order by排序

子查询

一个sql的查询结果,为另一个sql的查询条件

--查询工资最高的人的信息
-- 查询最高工资   maxSalary
select max(salary)
from employees   ---maxSalary

select * 
from employees
where salary = (select max(salary)
from employees)

1.子查询结果为一行一列

一般还会当做另一个sql的where条件来用

--查询工资大于平均工资的人的信息
--1.查出平均工资    avgSalary
select avg(salary)
from employees

--2.以平均工资作为条件查询员工信息  where salary>avgSalary
select * 
from employees
where salary > avgSalary

--3.组装
select * 
from employees
where salary > (select avg(salary)
from employees)

2.子查询结果为n行一列

会作为另一个sql的查询条件,一般用作枚举查询

--查询和last_name='King'的员工在同一个部门的所有员工信息
--1.查'King'在哪个部门
select department_id
from employees
where last_name='King'   ----x1,x2
--2.查询在x1和x2部门的人
select employee_id
from employees
where department_id in (x1,x2)
--3.组装
select employee_id
select *
from employees
where department_id in (select department_id
         from employees
         where last_name='King')

3.子查询结果为n行n列

结果作为另一个sql的数据来源表,写在from后面

--查询工资最高的前十个人
--1.给salary进行排序
select *
from employees
order by salary desc
--2.给排序的结果添加rownum  t1
select t1.*,rownum
from t1

--3.组装
select t1.*,rownum
from (select *
from employees
order by salary desc) t1
where rownum<=10

4.分页查询

--需求:工资降序排序,每页十条,查询第二页
--工资降序排序,查询第11条到第20条
--1.将工资降序排序
select *
from employees
order by salary desc
--2.给降序的结果添加rownum
select t1.*,rownum r
from (select *
		from employees
		order by salary desc) t1
--3.使rownum能大于某个数
select *
from (select t1.*,rownum r
		from (select *
				from employees
				order by salary desc) t1)
where r>=11 and r<=20......

注:三层嵌套
内层:排序
中间:给排序的结果添加伪列rownum
外层:把伪列变为实际的一列

表连接

查询结果分别在两张表中,想要得到完整结果,需要从两张表中找数据

1.内连接

关键字:[inner] join
语法规则:from 表1 [inner] join 表2 on 表1.字段名=表2.字段名
注意:内连接只展示两表之间有关联的内容,如果有一条数据在另一张表中没有与之关联的数据,内连接会舍弃此数据

--使用内连接查询员工id,姓名,工资,部门编号,部门名
select e.employee_id,e.first_name,e.salary,e.department_id,d.department_name
from employees e inner join departments d
on e.department_id = d.department_id

2.外连接

  • 左外连接
    关键字:left [outer] join
    语法规则:from 表1 left [outer] join 表2 on 表1.字段名 = 表2.字段名

左表的所有内容全都展示,右表只展示与左表相关内容

--使用左外连接查询员工id,姓名,工资,部门编号,部门名
select e.employee_id,e.first_name,e.salary,e.department_id,d.department_name
from employees e left outer join departments d
on e.department_id = d.department_id
  • 右外连接
    关键字:right join
    语法规则:>from 表1 right [outer] join 表2 on 表1.字段名 = 表2.字段名

  • 全外连接
    关键字:full join
    语法规则:>from 表1 full [outer] join 表2 on 表1.字段名 = 表2.字段名

3.表连接的应用

--需求:查询部门信息:部门编号,部门名称,部门所在地标号,部门所在城市
--表连接  departments  lcoations   链接条件 d.location_id = l.location_id

select *
from departments d left join locations l
on d.location_id = l.location_id



--需求:查询员工的工号,名字,工资,部门编号,部门名称,部门所在地编号,部门所在城市
-- 表连接  employees departments lcoations
--1.链接 employees departments
select *
from employees e left join departments d
on e.department_id = d.department_id
--2.将上述结果与locations链接
select *
from employees e left join departments d
on e.department_id = d.department_id
left join locations l
on d.location_id = l.location_id



--需求:查询员工的工号,名字,工资,领导编号,领导名字
--表连接  员工表(employees)  领导表(employees)  自连接
--物理上是同一张表,逻辑上是两张表
select e1.*,e2.*
from employees e1 left join employees e2
on  e1.manager_id = e2.employee_id

建表

create table 表名(
	字段1的名字  数据类型  (约束),
	字段2的名字  数据类型  (约束),
	.......
	字段n的名字  数据类型  (约束)
)

数据类型

  • 1.数字类型

number(x1) ----> 该字段只能保存数字,是个整数,最大有x1位
number(4) -----> 最大能保存9999
number(x1,x2) ---->该字段只能保存数字,可以保存小数,小数位数最多有x2位,整数位数最多有x1-x2位
number(5,2) ---->999.99
double integer

  • 2.字符串类型

可变长字符串
varchar2(n) —> 该字段能保存字符串,字符串最大有n个字符
varchar2(200) —>最大能写200个字符
如果我存的内容不够200,不够就不够

定长字符串
char(n)
char(200) —>该字段只能存200个字符,不能多也不能少
如果我存的内容不够200,在后面补空格,直到补够为止

  • 3.日期

date -------->日期

  • 4.补充

club:大文本域,可以保存很多字符串,varchar2最大能保存4000个字符
blub:二进制文件,可以保存图片,音乐,视频…

约束

  1. 主键约束(primary key)
    要求该字段的值不能为空,不能重复
    举个栗子: 身份证ID,学号,工号…
  1. 非空约束(not null)
    要求该字段的值不能为空
    栗子: 姓名
  1. 不可重复(unique)
    要求该字段的值不能重复
  1. 自定义约束(check)
    栗子:
    银行卡密码(pwd)必须六位
    check(length(pwd)=6)
    必须要以qq邮箱注册(email)—> 结尾 @qq.com
    check(email like ‘%@qq.com’)
  1. 外键约束(foreign key)
    语法: references 表名(字段名)
    作用:使字段的值只能从关联的表中的字段取值,或者是null
    要求:先有外键关联的表,再有存在外键的表
班级表 
   c_id
   c_name
   
学生表
    s_id
    s_name
    c_id
   
create table t_cla(
       c_id number(2) primary key,
       c_name varchar2(200)
)

create table t_stu(
       s_id number(4) primary key,
       s_name varchar2(200),
       c_id references t_cla(c_id)
)

增删改操作

CRUD:增删改查

1.增加操作

insert into 表名 (字段1,字段2,字段3…) values (字段1对应的值,字段2对应的值…)
注意:添加时只需保证前面的字段名与后面的字段值一一对应,不需要与表中的字段顺序完全一致
添加时可以不写字段名,但是要保证字段值的顺序与表中字段的顺序完全一致

2.删除操作

delete [from] 表名 [where 限制条件]
作用:将符合限制条件的数据删除
注意:如果没有where限制条件,将会删除表中的所有数据
–删除person_id = 3 的数据
delete from t_person where person_id=3
delete t_person —>删除表格中的所有数据
drop table 表名 —>删除表格

3.修改操作

update 表名 set 字段1=新值,字段2=新值… [where 限制条件]
作用:将符合限制条件的记录中的字段改为新的值
注意:如果没有限制条件,会将表中的所有数据的该字段都修改为新的值

SQL的分类

dql:数据查询语言 select
dml:数据控制语言 insert delete update
ddl:数据定义语言 create drop
tcl:事务控制语言 commit(提交) rollback(回滚)

事务

在sql运行中,多个sql语句要不一起执行成功,要不一起执行失败

  • 事务的运行原理

原子性:在同一个事务的sql不可分割,要不同时成功,要不同时失败
一致性:一旦提交事务,在回滚段中的内容会完全复制到原始数据中,提交之前的查询,与提交之后的查询结果一致
隔离性:在事务没有提交或者回滚时,其他用户不可得知事务中的内容
持久性:一旦提交或者回滚事务,事务堆数据库的影响是永久的不可修复的

序列

oracle提供的一个可以自动生成用不重复的数字的工具

创建序列
create sequence 序列名 [start with 数字]

create sequence seq_person

drop sequence 序列名

使用
序列名.nextval -->获取当前值然后序列+1
序列名.currval -->获取当前值,但是不增加

1.视图

将一个dql的查询结果当做一张表来进行使用

创建视图
create view 视图名 as dql(查询语句)

create view view_per as select * from t_person

drop view 视图名

select * 
from view_per

作用:

1.将复杂的sql简单化
​ 2.对开发者屏蔽底层信息

注意:

视图将一个dql语句保存起来
使用视图可以提高查询效率 错XXXXXXXXXXXXXXXXXXXXXXXX

2.索引

数据库给一张表创建的目录,在做dql(查询),如果使用了索引查询,查询速度会大大提高

创建:
create index 索引名 on 表名(字段名) --给表中的某个字段添加了索引
create index stu_index on t_stu(stu_id)

drop index 索引名

使用:自动使用(只针对有索引的字段)
select * from t_stu where stu_id=5; ---可以使用索引

注意:

​ 1. 给表中的所有字段都添加索引?

  	错,索引可以提高查询效率,但是会降低增删改效率

​ 2. 应该哪些字段添加索引

     主键自带索引,不用手动创建,添加索引的字段最好有唯一约束
3. 添加索引的字段不能经常被修改	

你可能感兴趣的:(学习笔记,oracle,sql)