Oracle---笔记(二)---Group子句+having子句+DML操作+SQL92多表链接+SQL99多表链接

1.Group 子句

用于将表中的数据分成若干个小组,在每个组中进行统计
语法:
select column, group_function(column)
from table
[where condition]
[group by group_by_expression]
[order by column];

解释:group_function:分组函数(count,avg,max,min,sum)
where condition:where子句,即查询条件语句,可有可无
group by group_by_expression:按照xxx表达式或列来分组
order by column:排序子句
注意事项:
1… 在SELECT列表中的字段,如果没有包含在多行函数中,则该字段必须出现在GROUP BY子句中。

例如:
select deptno,job,sum(sal) from emp group by deptno,job
2.包含在GROUP BY子句中的字段不必出现在SELECT列表(查询字段)中。
例如:
select deptno, avg(sal) from emp group by job, deptno;
3.如果没有使用group by子句,那么字段(或单行函数)就不能和多行函数一起使用
例如,下面语句是错误的:
select deptno, sum(sal) from emp
4.在where子句中不能使用分组函数
错误:select deptno,avg(sal) from emp where avg(sal)>1500 GROUP BY deptno

2.having子句

用于对分组后的数据进行筛选(过滤)
语法:
select column, group_function(column)
from table
[where condition]
[group by group_by_expression]
[having group_condition]
[order by column];
如果一个sql语句中同时需要对分组前数据进行筛选,对分组后数据也要筛选,还要根据某个字段排序,此时各个子句的顺序是?
顺序:where—>group by—>having—>order by
注意:我们可以给分组函数取别名,但是在having子句中不能使用分组函数的别名
错误:

select deptno,max(sal) 最大工资 from emp GROUP BY deptno having 最大工资>3000
正确:
select deptno,max(sal) 最大工资 from emp GROUP BY deptno having max(sal)>3000

3.DML操作

3.1 插入数据

使用insert语句向表中插入一行或多行记录。

A.插入记录值

一次插入操作只插入一条记录
语法:INSERT INTO table [(column [, column…])] VALUES (value [, value…]);
解释:
(column [, column…]):表示要插入值的字段列表(多个字段),多个字段之间用逗号隔开
(value [, value…])):提供给每个字段的值,它的数目要和字段的数目对应.字段名要和字段值对应。
插入记录值又分为两种情况:
1.插入全部列,即每个列(字段)都插入值
例如:
INSERT INTO emp(empno,ename,JOB,MGR,HIREDATE,sal,COMM,DEPTNO) VALUES(7787, ‘张小龙’,‘CLERK’,7566,SYSDATE,6000,100,20)
如果要给表的全部字段插入值,可以省略字段列表不写
INSERT INTO emp VALUES(7789, ‘张大龙’,‘CLERK’,7566,SYSDATE,7000,100,30)
2.插入部分列,即给一部分列(字段)插入值
此时不能省略字段列表,被省略的字段要满足以下2个要求之一:
1)该字段允许为null
2)该字段在表设计时,有一个默认值
例如:
– 插入部分字段:添加员工,只添加工号,姓名,职位,工资四个字段
INSERT INTO emp(empno,ename,job,sal) VALUES(8812,‘宁采臣’,‘CLERK’,5000)

B.插入查询结果

即使用insert语句将一个select语句的查询结果插入到一个表中,此时就插入了多条记录。
语法:insert into table(字段1,字段2…) select 字段1字段2,… from tablename2
使用该语法时,要求被插入数据的表table要存在
1)先创建一张表emp_temp
create table emp_temp as select * from emp where 1=2
以上sql表示将emp表的结构拷贝到emp_temp上,但不拷贝数据和约束, where 1=1代表拷贝emp表的结构和数据
2)使用上面的语法将emp表的查询结果批量插入到 emp_temp
insert into emp_temp(empno,ename,sal) select empno,ename,sal from emp
3.2 修改数据
语法:
Update table set 字段1=值1, [字段2=值2]…
[ Where 条件]
例如:
Update emp set sal=sal+100, comm=nvl(comm,0)+50 Where ename=‘SMITH’

如果省略where子句,就代表表的所有记录

3.3 删除数据

1.使用delete删除
语法:delete [from] table [where 条件]
如果带了where子句,表示要删除满足条件的记录,省略where子句将删除所有记录
delete from emp where empno in(7787,7789,8812)
2.使用truncate删除
语法:truncate [table] table_name;
Truncate删除是删除表的所有记录,与不带where子句的delete语句功能相同
例如:truncate table emp_temp
Delete删除和truncate删除的区别
1).delete删除数据会把删除的每条记录记录在日志中,存储到oracle服务器的日志文件中,而truncate删除不会保存日志,速度更快
2)Delete语句删除的数据在没有提交前可以回滚(撤销操作,恢复数据),truncate删除的数据不能回滚
注意:navicat客户端工具默认执行DML语句(insert,update,delete)时,会自动提交事务(对数据库的影响能永久保存起来,其它客户端工具都能看到最新的数据),提交后不能再回滚.
在sqlplus,PLSQL Developer中,执行DML语句不会提交事务,需要执行commit命令手动提交,提交后就不能回滚了。
在这里插入图片描述

回滚:rollback(撤销之前的DML操作,恢复数据)
在这里插入图片描述

4.SQL92多表连接

Sql92查询语法如下:
SELECT table1.column, table2.column FROM table1, table2 WHERE table1.column1 = table2.column2;

4.1等值连接:

等值连接在where子句上用等于号得到两个表都满足连接条件的数据
例如:
– 查询员工的工号,姓名,工资,部门名称,部门地址
select empno,ename,sal,dname,loc from emp,DEPT where emp.DEPTNO=dept.DEPTNO
注意:
1)如果用了2个表中同名的字段,就要在字段前加上” 表名.”或”表的别名.”做前缀
select empno,ename,sal,dname,loc from emp,DEPT where emp.DEPTNO=dept.DEPTNO
select empno,ename,sal,dname,loc from emp t1,DEPT t2 where t1.DEPTNO=t2.DEPTNO
2)如果给表取了别名,那么就不能再使用表的真名,只能用别名
错误:
select empno,ename,sal,dname,loc from emp t1,DEPT t2 where emp.DEPTNO=t2.DEPTNO

3)可以在where子句中使用And来加入更多的查询条件
– 查询员工的工号,姓名,工资,部门号,部门名称,部门地址且部门号<30的员工
select empno,ename,sal, t1.DEPTNO, dname,loc from emp t1,DEPT t2 where t1.DEPTNO=t2.DEPTNO and t1.DEPTNO<30

4)如果查询的字段只在一张表中出现,则可以不在前面写前缀”表名.”或“表别名.”

4.2左外连接

返回左边表的全部行,右表不满足条件的行用NULL填充
语法:
SELECT table1.column, table2.column
FROM table1, table2
WHERE table1.column = table2.column(+);
语法中table1是左表,table2是右表(右表满足条件的记录要少些)
例如:
select empno,ename,sal, t1.deptno,t1.dname from dept t1,emp t2 where t1.DEPTNO=t2.DEPTNO(+)

4.3右外连接

返回右边表的全部行,左表不满足条件的行用NULL填充
语法:
SELECT table1.column, table2.column
FROM table1, table2
WHERE table1.column (+)= table2.column;
语法中table1是左表,table2是右表,(+)要写在记录数少的表的后面
select empno,ename,sal, t2.deptno,t2.dname from emp t1 , dept t2 where t1.DEPTNO(+)=t2.DEPTNO

4.4自连接

把一张表当成2张表来看,需要给表取别名,实现特殊的需求。
例如
– 查询工资比领导还要高的员工的编号,姓名及领导姓名
select e1.empno 员工编号,e1.ename 员工姓名,e2.ename 领导姓名 from emp e1,emp e2 where e1.mgr=e2.empno and e1.sal>e2.sal

自连接就是特殊的等值连接或外连接

5.SQL99多表连接

1.using子句

Using子句可以选择使用两个表的哪个同名字段来建立等值连接
语法:
Select 字段… from 表1 join 表2 using(字段)
例如:
select ename,sal,dname,DID from emp join dept using(DID)
– 等价于sql92中的如下写法
select ename,sal,dname,dept.DID from emp,dept where emp.DID=dept.DID

2.内连接

语法:
Select 字段… from 表1 [inner] join 表2 on 表1.column_name =表2.column_name
内连接不要求建立连接的字段的名称相同,即建立连接的字段可以相同也可以不同.
我们可以在内连接语句后加where子句,where子句上写过滤条件,on子句指定连接条件
select empno,ename,job,dept.deptno,dname from emp JOIN dept on emp.DEPTNO=dept.DEPTNO where job=‘SALESMAN’
– 也可以将连接条件和过滤条件写在一块,用()包裹起来
select empno,ename,job,dept.deptno,dname from emp JOIN dept on (emp.DEPTNO=dept.DEPTNO and job=‘SALESMAN’);
多表连接规律:连接n张表,至少需要n-1个连接条件。
Sql99的内连接就等价于sql92的等值连接,返回2个表都满足连接条件的数据

3.外连接

统一语法:
SELECT table1.column, table2.column
FROM table1
LEFT|RIGHT|FULL [OUTER] JOIN table2
ON table1.column_name = table2.column_name;
说明:outer可以省略
左外连接:left join
是在连接过程中,返回左边表的所有行(无论是否满足连接条件),右边表中不满足条件的行用NULL填充

右外连接:right join
是在连接过程中,返回右边表的所有行(无论是否满足连接条件),左边表中不满足条件的行用NULL填充

全外连接:full join
例如:
select ename,sal,d.DEPTNO,d.DNAME from dept d left join emp e on d.DEPTNO=e.deptno;
select ename,sal,d.DEPTNO,d.DNAME from emp e right join dept d on d.DEPTNO=e.deptno

猜你喜欢

转载自blog.csdn.net/qq_41532872/article/details/86600080