大家好,又见面了,我是你们的朋友全栈君。
1、查询SELECT
由于之前安装的oracle数据库中选择了生成示例方案,oracle默认提供了三张数据表,分别是(emp,dept,salgrade)
此时数据显得很乱,我们可以通过设置显示的宽度以及每页显示的数据
SET LINESIZE 300;
SET PAGESIZE 30;
emp表
dept表
salgrade表
在编写SQL语句的时候需注意一个规则:关键字使用大写字母,其他非关键字使用小写字母(其实小写也是可以的,但是建议使用,比较规范专业一点)
可以通过DESC
来查看表的结构
表emp,用来保存雇员信息
dept表,保存部门信息
salgrade表,保存薪资等级信息
简单查询
数据库有一门专门术语自己的语言,其语言的核心就是查询语句,难点也是查询,重点也是查询,使用最多的也是查询,叫做结构化查询语言(Structured Query Language)
SQL分类
数据操纵语言(DML Data Manipulation Language):
SELECT(查询)、INSERT(插入)、UPDATE(修改)、DELETE(删除)
数据定义语言(DDL Data definition Language):
CREATE ALTER DROP RENAME TRUNCATE
数据控制语言(DCL Data Control Language):
GRANT(比如说授权远程连接、权限授权等等)
事物Transaction:commit(提交) rollback(回滚)
SELECT * SELECT字句
FROM 数据来源(想要查询数据的表) FROM字句
以上的字句在数据库中执行指令的时候是有顺序的,先执行FROM字句,在执行SELECT字句,*表示所有信息
第二种形式
SELECT 字段名,字段名,字段名.......
FROM 数据来源
通过指定字段查询,显示的只有指定的字段信息
DEMO:查询每个员工的编号,姓名,职位,薪资
SELECT EMPNO,ENAME,JOB,SAL
FROM emp;
解决重复的数据使用关键字DISTINCT
SELECT DISTINCT JOB
FROM emp;
使用DISTINCT只有查询的所有字段内容相同才会认为是重复的
DEMO:查询每个雇员的编号、姓名、职位、基本年薪
SELECT EMPNO,ENAME,JOB,SAL*12
FROM emp
可以在sql语句中对数字类型的字段进行四则运算
上述查询出来的年薪显示的是SAL*12,显示不好看,也不好区分,我们可以用别名进行改进
使用别名,关键字AS,也可以省略AS
DEMO:使用别名进行查询
SELECT EMPNO AS 编号,ENAME 姓名,JOB AS 职位,SAL*12 AS 年薪
FROM emp;
限定查询
在实际开发过程中,基本查询相对用的很少,数据库中有成千上万条数据,如果单一的基本查询,而不给限定条件,严重的情况会导致服务器崩溃,影响还是很大的,所以实际开发中基本都是用限定查询,给出限定条件进行查询
SELECT *
FROM 数据来源
WHERE 过滤条件
使用关键字WHERE 进行过滤删选
WHERE字句经常和关系运算符一块使用,大于>、小于<,等于=,不等于<>,BETWEEN AND等等
关系运算符
DEMO:查询基本工资高于1500的雇员信息
SELECT *
FROM emp
WHERE SAL > 1500;
DEMO:查询职位不是销售人员的雇员编号、姓名、职位
在查询过程中,看清需求是要我们查询什么这个关键字眼,查询什么就在SELECT 后面跟字段名称,比如DEMO中,让我们查询雇员编号、姓名、职位,这三个字段名就跟在SELECT 后面,而职位不是销售人员则是过滤条件,放在WHERE 后面
SELECT EMPNO,ENAME,JOB
FROM emp
WHERE JOB<>'SALESMAN';
逻辑运算符
BETWEEN AND
使用BETWEEN AND 的时候小的数字或者日期放到AND前面,大的一个放到AND后面
DEMO:查询工资在1500-3000之间的雇员信息
以上两种方式使用第二种会更好,第一种数据库认为是两个条件判断,第二种则会被认为是一个判断条件,所以第二种效率高
OR
WHERE字句中有一个判断条件满足就能被查询出来
空判断
NULL
DEMO:查询没有佣金的雇员信息
IN
DEMO::查询编号是7369,7765,7788的员工信息
不在这个范围,在IN前面加上NOT
模糊查询
1、_:表示任意字符
2、%表示任意位数的任意字符
3、要实现模糊查询需要使用关键字‘LIKE’
DEMO:查询姓名是以A开头的雇员信息
DEMO:查询姓名的第二个字母是A的员工信息
DEMO:查询姓名包含A的雇员信息
排序查询
排序查询就是讲查询的结果按照指定的字段进行升序或者降序显示,这个字段必须是数字或者日期类型的才有意义
使用关键字ORDER BY,默认是以升序排列显示,ASC(升序)/DESC(降序)
基本语法如下
3 SELECT *
1 FROM 数据来源
2 WHERE 过滤条件
4 ORDER BY 排序字段 ASC/DESC
DEMO:查询所有的员工信息,按照薪资降序排列
DEMO:查询所有的销售人员信息,按照雇佣的日期从早到晚排列
DEMO:查询每个员工的编号,姓名,年薪,按照年薪升序排列
总结:1、ORDER BY 子句在SELECT子句之后执行
2、排序的字段必须是数字或者日期才有意义
多表查询
如果要从多张数据表中查询数据,就需要用到多表查询,多表查询又叫做连接查询,FROM子句中可以有多个数据来源,多表查询就需要有多个数据来源
DEMO:实现多表查询
查询两张表,显示了60行数据,emp表中15条数据,dept中4调数据,15*4=60条,
最终多表查询出的数据就是两张表中的数据量的乘积,这样数据显然存在重复,这种现象叫做笛卡尔积,在查询的时候需要消除笛卡尔积,只需要在查询中增加一个WHERE子句,WHERE子句的过滤条件是两张数据表中的关联字段相等
DEMO:消除两张数据表的笛卡尔积
总结:1、多表查询就是从多张数据表中查询数据
2、多表查询又叫做连接查询
3、多表查询会产生笛卡尔积,在数据量大的时候不要使用多表查询(数据量小的时候可以使用)
DEMO:查询每个雇员的编号,姓名,职位,工资,部门名称,部门位置
DEMO:查询每个雇员的编号,姓名,职位,工资,工资等级
DEMO:查询每个雇员的编号,姓名,职位,工资,工资等级,部门位置和名称
连接查询
连接查询就是多张表进行连接然后查询数据,多表查询其实就是连接查询,连接查询分为内连接查询和外连接查询
内连接查询:只有满足条件的数据才会被显示
外连接查询:可以控制不满足条件的数据是否显示
DEMO:查询出雇员的编号,姓名,职位,薪资,工资等级,部门的位置和部门的编号
发现emp表中的张三没有查询到,原因是以上多表查询是一个内连接查询,内连接查询的特征是满足过滤条件的数据才会被显示
对于emp表中的张三数据来说,DEPTNO字段为null,很显然不满足WHERE e.DEPTNO=d.DEPTNO,自然不显示班长的数据,以上是内连接查询的特征导致的,如果不满足条件的数据也显示出来,需要用到外连接查询,外连接查询又分为:左外连接查询和右外连接查询、全外连接查询
左外连接查询:可以让左表不满足条件的数据也显示
右外连接查询:可以让右表不满足条件的数据也显示
全外连接查询:可以让左表和右边不满足条件的数据都显示出来
DEMO:使用左外连接对上个DEMO进行处理
以上实现了左外连接查询,发现了左外连接查询的(+)是放到右边的,查询结果是:左表中不满足条件的张三信息也显示了
总结:1、内连接查询,只显示满足过滤条件的数据,之前的多表查询就是一个内连接查询
2、外连接查询,可以控制不满足条件的数据是否显示,外连接查询分为:
左外连接查询
右外连接查询
全外连接查询
3、可以在过滤条件中使用(+)来实现左或者右外连接查询,但是这种方式是Oracle特有的方式,在mysql中不能使用
内连接查询的其他实现方式
在上面我们知道了多表查询就是内连接查询,内连接查询的特征是:不满足条件的数据不会被显示,除了默认(FROM 数据表,数据表)方式我们还可以使用INNER JOIN 关键字来实现内连接查询
DEMO:使用INNER JOIN ON(后面跟相等的字段)来实现内连接查询
DEMO:查询出雇员的编号,姓名,职位,部门名称,部门位置,薪资等级
第一种内连接查询:在FROM 子句中查询多个数据来源,在WHERE子句中去掉笛卡尔积
第二种内连接查询:使用INNER JOIN 连接数据来源,在ON关键字之后去掉笛卡尔积
通用的外连接查询
其实oracle还有一种特有的方式实现左右外连接查询,那就是OUTER JOIN ON
,之前是用到了(+)的形式
DEMO:使用通用方式实现左外连接查询
DEMO:使用右外连接查询
DEMO:使用全外连接查询
总结:1、内连接查询的方式有两种:
a.直接在FROM之后跟上多张数据表,在WHERE条件中去掉笛卡尔积
b.使用INNER JOIN 进行连接,在ON 之后去掉笛卡尔积
2、通用的外连接查询
a.左外连接:使用LEFT OUTER JOIN 实现,在ON 之后去掉笛卡尔积
b.右外连接:使用RIGHT OUTER JOIN 实现,在ON 之后去掉笛卡尔积
c.使用FULL OUTER JOIN 实现,在ON 之后去掉笛卡尔积
常用的函数
Oracle提供了很多函数,有几十个,但是常用的不多,函数就是Oracle定义好了的,我们可以直接使用即可
COUNT(/字段名):统计出查询到的数据量
SUM(字段):计算出指定字段的数据之和(字段是数字才有意义)
AVG(字段):计算出指定字段中平均值(字段是数字才有意义)
MAX(字段):统计出指定字段中最大值(字段是日期或者数字才有意义)
MIN(字段):统计出指定字段中最小值(字段是日期或者数字才有意义)
SYSDATE:取得当前日期
NVL(eExpression1,eExpression2)参数eExpression1,eExpression2
如果eExpression1的计算结果为null值,则NVL()返回eExpression2.如果eExpression1的计算结果不是null值,则返回eExpression1。eExpression1和eExpression2可以是任意一种数据类型。如果eExpression1和eExpression2的结果皆为null值,则NVL()返回NULL
DEMO:查询雇员的最高工资和最低工资
DEMO:查询雇员的平均工资和工资之和
DEMO:查询EMP表中人数的总和
面试题:请说明COUNT()、COUNT(字段)、COUNT(DISTINCT 字段)三者的区别
COUNT(*):统计出所有的数据量,没有过滤功能
COUNT(字段):统计出指定字段不为null的数据量,有过滤功能
COUNT(DISTINCT 字段):统计指定字段不为空并且去掉重复数据之后的数据量
总结:统计函数常常和分组查询一块使用
分组统计查询
之前提到过统计函数都是为分组函数服务的,那么什么是分组查询,如果要查询处每种职位的平均工资?如果要查询每个部门的人数?如果要实现类似的需求就要使用分组统计查询,基本语法如下:
并标注执行顺序
4 SELECT *
1 FROM 数据来源,数据来源
2 WHERE 过滤条件
3 GROUP BY 分组字段
5 ORDER BY 排序字段 排序方式ASC/DESC
DEMO:查询出每个职位的平均工资
DEMO:查询出每个部门的名称及其人数
DEMO:查询出每个部门的名称、人数、以及每个部门的雇员的最高和最低工资
分组查询需要注意的几个问题
1、如果SELECT子句中使用了统计函数而同时有没有GROUP BY 子句,那么SELECT 子句中只能出现统计函数,不能出现其他任何字段
2、如果在SELECT子句中使用了统计函数同时有GROUP BY 子句,则在SELECT子句中只能出现统计函数和分组的字段,有其他的字段就会查询失败
3、如果SELECT子句中使用了嵌套的统计函数,则不管是否有GROUP BY 子句,那么SELECT子句中不能出现除统计函数之外的任何字段,就算是分组字段也不可以
DEMO:查询出平均工资高于2000的职位名称和平均工资
发现在WHERE子句中不能使用分组统计函数,此时需用到HAVING子句,HAVING子句常常和GROUP BY 一块使用,用于判断过滤的作用
使用HAVING 子句进行改进
HAVING子句
HAVING子句是对分组统计函数统计出的结果进行过滤的子句
基本语法及执行顺序
5 SELECT *
1 FROM 数据来源
2 WHERE 条件判断
3 GROUP BY 分组字段
4 HAVING 对统计函数进行判断
6 ORDER BY 排序字段 排序方式ASC/DESC
DEMO:查询出非销售人员的工作名称以及从事同一工作的雇员的月工资总和,并且要求从事同一工作的雇员工资合计大于五千,输出结果按照雇员的薪资之和进行升序排列
面试题:请说明WHERE子句和HAVING子句的区别?
WHERE子句在GROUP BY 子句之前执行,不能在WHERE 子句中使用统计函数
HAVING子句在GROUP BY 子句之后执行,可以在HAVING子句中对统计函数进行过滤
子查询
子查询就是讲一个SELECT查询的结果作为另外一个查询(主查询)的数据来源或者是判断条件的查询,常见的子查询有WHERE子查询,FROM子查询,SELECT子查询,HAVING子查询,EXISTS子查询
WHERE子查询
WHERE子查询就是在WHERE子句中继续使用查询,就是讲一个查询结果放在WHERE子句中再和另外一个字段进行过滤
DEMO:查询出低于平均工资的雇员信息
HAVING子句是对分组统计函数进行过滤的子句,也可以在HAVING子句中使用子查询,这就是HAVING子查询
DEMO:查询平均薪资高于所有员工平均工资的职位名称、以及职位的人数,这些高于平均工资的职位的平均工资
2、增加INSERT
INSERT:添加/插入数据
1、单行插入
INSERT INTO 表名(column1,column2,column3,column4) VALUES(value1,value2,value3.value4);
字段和values值要对应
--创建数据表
create table t_student(
sid number(3) primary key,
sname varchar2(20),
sage number(3)
);
--插入数据
insert into t_student(sid, sname) values(101, '张三');
insert into t_student(sid, sname) values(102, '李四');
insert into t_student(sid, sname) values(103, '李四');
COMMIT 提交
ROLLBACK 回滚
INSERT INTO 表名 VALUES(value1,value2)
COMMIT;--提交
2、多行插入
(1)多条数据插入
--创建数据表
create table t_class_copy(
cid number(4),
cname varchar2(20)
)
--插入多条数据
insert into t_class_copy(cid,cname) select cid,cname from t_class;
insert into t_class_copy(cid,cname) select cid,cname from t_class where cid = 1003;
(2)表结构的复制
a、复制表不包含数据
create table t_class_copy2 as select * from t_class where 1 <> 1;
create table t_student_copy as select * from t_student where 1 <> 1;
b、复制表包含数据
create table t_class_copy3 as select * from t_class;
(3)插入常量值
insert into t_class select 1005, 'java0320' from dual;
insert into t_class(cid) select 1005 from dual;
3、修改UPDATE
UPDATE:更新
语法:
UPDATE 表名 SET column1=value1,column2=value2...[WHERE columnN=valueN];
DEMO:更新学生表中 所有的记录的 sage 为18
UPDATE t_student set sage=18;
注意:
1、更新语句没有加入WHERE条件,表示更新所有的记录,所以需要慎用
2、oracle中判断数据库为空,使用IS NULL,不为NULL是IS NOT NULL
3、同时更新多个字段的时候需要把更新的字段列表和查询出来的字段列表的顺序类型个数要保持一致
4、删除DELETE
DELETE:删除
语法:
DELETE FROM 表名 [WHERE 条件];
DEMO:删除学生表中所有的数据
DELETE FROM t_user;
DEMO:删除学生表中ID为3的数据
DELETE FROM t_student WHERE sid=3;
这种删除方式是先将数据保存到内存中,然后提交,再统一删除,TRUNCATE可以删除数据,这里删除是删除所有的数据,是不能够带条件的
TRUNCATE table _class_copy;
DELETE和TRUNCATE的区别
1、delete是带条件删除,条件和update语句是一致的,如果delete不带条件,表示全表删除
2、delete删除数据的时候,是现将数据保存到内存中,可以回滚,而truncate删除数据不能够撤销,直接从硬盘中删除,所以慎用
3、truncate删除不可以带WHERE条件
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/151186.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...