--DQL:数据查询语言
功能:从数据库表中查询数据出来;对应到生活中的软件 百度搜索、查询;
select 语句
例如:用户信息表 user_tab
列:user_id 编号;
user_name 姓名
passwd 密码
phone 手机号
email 邮箱
create_date 创建日期
模拟场景:从user_tab中把想要的数据查询出来;
1.查询表中所有的数据:所有行,所有列;
select * FROM user_tab;
2.查询表中部分列信息:查询用户的姓名,电话,邮箱;
select user_name,phone,email from user_tab;
3.起名字
select user_name 姓名, phone 电话,email 邮箱 from user_tab;
4.查询名字叫“司马懿”的用户信息;
select * from user_tab where user_name='司马懿';
select * from user_tab where phone='12324679900';
查询名字叫“司马懿”和“张春华”的用户信息;
select * from user_tab where user_name='司马懿' or user_name='张春华';
select * from user_tab where user_name=any('司马懿' ,'张春华');
select * from user_tab where user_name in('司马懿' ,'张春华');
==》语法
1.查询表中所有的数据信息;
select * from 表名;
2.查询表中部分列信息:列名
select 列名1,列名2,列名3,... from 表名;
3.起别名: 列名 别名,列名2 别名
4.去重复数据,相同的数据只保留一行(行重复)
关键词:distinct
例如:
select distinct job, deptno from emp;
5.带有查询条件的查询语句;根据查询条件进行数据查询
一、单条件查询:一个查询条件
select * from 表名 where 查询条件;
查询条件:列名 运算符 搜索值 --(查询条件三要素)
备注:1)搜索值,除过数值以外,其他类型的字符都必须加单引号;
2)区分中英文,区分大小写
运算符:=,!=,<>,>,<,>=,<=
= 精确查询:将跟搜索值一模一样的数据查询出来;
!= 不等于,将跟搜索值不一样的数据全部查询出来;
二、多条件查询:多个查询条件
条件连接: and or
查询条件 and 查询条件:功能:将同时满足两个查询条件的数据查询出来;
查询条件 or 查询条件:功能:将满足其中一个查询条件的数据都查询出来;
多条件运算符: in between...and... not
in 多值运算符
用法: 列名 in(搜索值1,搜索值2,...) 功能:将满足这几个搜索值的数据都查询出来;
等价于: 列名=搜索值1 or 列名=搜索值2 or ... 列名必须一样,是同一个列
备注:当搜索值是字符串,一定要加单引号: 列名 in('搜索值1','搜索值2',...)
between ... and ... 查询一个区间范围内的数据,多用在数值类型的数据中居多
用法: 列名 between 值1 and 值2
等价于:列名>=值1 and 列名<=值2
备注:值1<值2,包含了临界值(上下限)
not(1个或者多个查询条件)
用法: not 取反,功能:是括号中查询条件取反的数据
例如:select * from emp where not(sal between 2000 and 3000);
6.模糊查询:将跟搜索值类似的数据都查询出来
关键字:like ,不能单独使用,必须结合通配符 %或者_ 一起使用; --在查询条件中,like 运算符
% 代表0个或者任意多个字符;
张%:代表张,张三,张三丰,张*******,即指以张开头的数据;
%张:代表以张结尾;
%张%:代表,包含张的数据
_ 代表1位任意字符 ,占位符
例如:查询名字中包含“司马”的用户信息;
select * from user_tab where user_name like '%司%马%';
例如:查询名字中包含“司马”的用户信息,并且手机号码倒数第二位是6;
select * from user_tab where user_name like '%司%马%' and phone like '_________6_';
select * from user_tab where user_name like '%司%马%' and phone like '%6_';
7.查询结果排序
关键词:order by 列名 排序方式(可以定义,默认升序);
升序:asc
降序:desc
==>
select * from 表名 [where 查询条件] order by 列名1 asc,列名2 desc,...;
备注:多个列参与排序,排序的先后顺序会直接影响查询结果
例如:查询部门编号为10和20的员工信息,然后请按照部门编号升序排,同一部门再按照薪水降序排;
select * from emp where deptno in(10,20) order by deptno,sal desc;
练习:
表名: emp 职工表
有8列:
empno 职工编号
ename 职工姓名
job 岗位
mgr 职工的主管编号
hiredate 入职日期
sal 薪水
comm 津贴
deptno 职工所在部门的编号
1. 查询职工表的所有数据;
select * from emp;
2. 查询职工表的职工姓名、岗位、入职日期、薪水
3. 查询职工表的岗位、部门编号 ;
select job, deptno from emp;
练习:带条件查询
1. 查询职工编号是7698的职工
2. 查询岗位是CLERK的职工;
3. 查询薪水高于2000的员工 ;
4. 查询薪水高于2000,并且部门编号是10的员工信息;
select * from emp where sal>2000 and deptno=10;
select * from emp where sal>2000 and (deptno=10 or deptno=20);
select * from emp where sal>2000 and deptno in(10,20);
select * from emp where sal>2000 and deptno=any(10,20);
5. 查询薪水在2000~3000之间的员工信息;
select * from emp where sal>2000 and sal<3000;
select * from emp where sal between 2000 and 3000;
练习:多条件查询、模糊查询
1. 查询薪水高于1000,并且岗位是CLERK的员工;
select * from emp where sal>1000 and job='CLERK'
2. 查询主管编号是7902, 或者部门编号是10的员工;
3. 查询部门编号是10、20 这2个部门的员工 ----列是一样,同是有多个值
select * from emp where deptno in (10,20);
4.查询名字是ALLEN BLAKE CLARK MILLER 这4个人 ----用模糊查询; 类似于xxx,可以将这4个人查询出来
5. 查询名字是ALLEN BLAKE MILLER 这3个人 ----用模糊查询; 类似于xxx,可以将这3个人查询出来
6. 查询名字是ALLEN MILLER 这2个人 ----用模糊查询; 类似于xxx,可以将这2个人查询出来
练习:排序、多条件运算符
1.查询姓名不是SMITH , 并且薪水要在 950~3000之间的员工
select * from emp where ename!='SMITH' and sal between 950 and 3000 ORDER by sal desc
2. 查询部门编号是20、30的员工,然后按照薪水升序排
select * from emp where deptno in('20','30') order by sal asc,deptno desc
3.查询岗位是CLERK,或者薪水>2000,然后职工编号降序排
select * from emp where job='CLERK' or sal>2000 order by empno desc;
练习补充:
4.将姓名和薪水两列连接起来显示“xxx的薪水是多少”这样的信息; --一列
select ename,sal from emp;
select ename||'的薪水是'||sal 职工薪水 from emp;
|| 拼接符,作用:用来拼接列或者字符串的
, 列的分隔符,用来分隔列的
给列起别名: 列名 别名,列名2 别名
7.查询comm为空值的职工信息;
select * from emp where comm is null;
特殊:null 空值
表示的未知的值,不确定的值;空值的运算符 is ,其它运算符都不可以;
not null 非空 ,运算符 is
特点:任何值去跟空值做运算,结果都是空值;--会有问题,跟实际不相符了,比如:职工总收入 select sal+comm from emp;
解决办法:空值转换函数,作用;用来转换空值,把空值变成一个确定的,实际的值 nvl(参数1,参数2),参数1 表示待转换空值的列名,参数2,确定的实际的值
即,当参数1是空值的时候,就用参数2来代替。
例如:查询职工的姓名,薪水,津贴,以及总收入;
select ename,sal,comm,sal+comm,sal+nvl(comm,0) from emp;
5.将下面SQL分别执行,能得出什么结论?(扩展练习) and or 优先级的结论
select * from emp where deptno='30' and mgr='7698' or job='CLERK';
select * from emp where job='CLERK' or deptno='30' and mgr='7698';
结论:and 优先级 高于 or
----------------------------------------------------------------------------
select * from 表名 [where 查询条件] order by 列名 排序方式,列名2 排序方式;
查询条件:列名 运算符 搜索值
---------------------- DML :数据操作语言
insert 语句:插入语句;功能:将数据插入表中;结果:表中数据量增加了,以行为单位 ;对应到软件中 :注册,加入购物车
update 语句:更新修改数据;功能:将表中原有的数据进行修改;结果:表中数据量不变,但是内容变了;对应到软件中:修改个人信息
delete 语句:删除语句;功能:如果表中数据不需要了,可以进行删除,结果:表中数据量减少,以行为单位;对应到软件中:清空购物车,删除
--------------------------------数据类型:每个列下面放什么数据,都是有类型限制的
常见:char、varchar2、date 、number
char 字符类型:固定长度的字符类型,如果长度不够就会在后面补足空格,优势,存储效率高;
varchar2 字符类型:可变长度的字符类型, 优势,节省空间
例如: char(10) --固定存放10位长度的字符
abcde --> abcde 补足5个空格
varchar2(10) --最多可以存放10位长度的字符
abcde -->abcde
create table t0720(
id1 char(10),
id2 varchar2(10));
insert into t0720(id1,id2) values('abcde11','abcde1');
select * from t0720;
------------------------------
date 日期类型
特点:支持加减运算
常用的关键字:sysdate
create table t0720_1(
ename varchar2(30),
hiredate date);
SELECT * FROM t0720_1;
insert into t0720_1(hiredate, ename) values( sysdate,'sunsun');
insert into t0720_1 values('sunsun', sysdate-5);
insert into t0720_1 values(sysdate-5);
insert into t0720_1 values('孙孙','02-9月-2018');
insert into t0720_1 (ename,hiredate) values ('yangfengfan',sysdate);
两个函数:日期数据的转换函数
to_char(参数1,参数2),作用,将日期类型的日期数据转换成功字符类型的日期数据
两个作用:1.规范日期的显示格式;常用的通用格式:'yyyy-mm-dd hh:mi:ss '
2.用在查询条件中
例如:规范日期的显示格式:查询职工的姓名,入职日期
select ename, hiredate, to_char(hiredate,'yyyy-mm-dd')from emp;
查询入职日期在1981年10月1日之前入职的员工信息;
select * from emp where hiredate<'1981-10-01';
select * from emp where hiredate<'01-10月-81';
select * from emp where to_char(hiredate,'yyyy-mm-dd')<'1981-10-01'; to char日期类型转字符,to date字符类型转日期,两种转的过程中都是用'yyyy-mm-dd'
to_date(参数1,参数2),作用,将字符类型的日期数据变成日期类型的日期数据,主要是在插入语句中使用
例如:插入入职日期是1999-10-10的人员信息;
insert into emp values(3456,'孙',null,'',to_date('1999-10-10','yyyy-mm-dd'),5000,null,10);
select * from emp;
参数1:待转换的原数据;参数2:格式
-------------------number 数值类型
number(参数1,参数2) 支持整数和小数: 参数1-参数2 ,表示整数位最多存放几位
例如: number(5,3) 整数位最多存放2位 -99~99
66.6546745674 -->66.655
4.44543423425 -->4.445
create table t0720_2(num number(5,3));
insert into t0720_2 values(4.44543423425);
select * from t0720_2;
例如:number(5,-3) 整数位最多存放8位
2342343.3456343456 --> 2342343.346
00000099.9999999-->0
000999.99999-->1000
create table t0720_3(num number(5,-3));
insert into t0720_3 values( 2342343.3456343456);
insert into t0720_3 values(000999.9999999);
select * from t0720_3;
例如: number(5,0) 整数位最多放5位
2342343.356357567--》
99.9999999--》100
99.49999999--》99
create table t0720_4(num number(5,0));
insert into t0720_4 values(2342343.356357567);--》报错了,超出精度范围
insert into t0720_4 values(099.49999999);
select * from t0720_4;
number(p,s) 总结
1.p-s 表示整数位最多存放几位;
2.s>0,小数点向右至s位置,四舍五入;<0,小数点向左至s位置,四舍五入;=0,就在小数点位置,进行四舍五入;
3.p 的取值范围 1 到 38
s 的取值范围 -84 到 127
4.当s=0,number(p,s)简写 number(p)
------------------------- insert 语句 ------------------
想清楚:
1.往哪个表插入数据;--》表名
2.往哪些列插入数据;--》列名,类型
3.插入的数据是什么?--》插入的值
==》语法
insert into 表名(列名1,列名2,...) values(值,值2,...);
如果给表中所有列插入数据,可以简写:
insert into 表名 values(值,值2,....); --值的顺序要和初始定义表的列的顺序一致
注意:1.值的个数跟列的个数要一致;
2.值的类型和列的类型要匹配
3.凡是有特殊含义的,例如:列名、关键字 不能加单引号;加了就变成了普通的字符串,失去原有的含义;
但是插入的值,查询的搜索值,如果是字符串,就必须加单引号。
例如:往用户信息表中插入一个用户信息:用户编号,用户信息,手机号,日期,密码;
select * from user_tab;
insert into user_tab(user_id, user_name, phone, create_date, passwd) values(200023,'sunsun',null,sysdate,null);
insert into user_tab values(2345235,'sunsun2',null,'',null,null);
练习:在职工信息表中,插入2个职工信息,分别使用一种语法 ,注意(empno不能为空,不能重复;deptno 取值:10,20,30任意一个)
select * from emp where ename='SUN2'
insert into emp values(1236,'SUN2',null,null,'12-12月-2018',null,null,10);
----------------- -事务 -----------------
事务:一旦执行DML语句,就会自动开启一个事务,后面所有的DML语句都会进入事务;不会自动结束,需要手动结束;
commit; 提交
rollback; 回滚 ,提交之前操作才有效果
特殊:DDL语言(create/alter/drop),自带提交
-------------------------delete 语句
想清楚:
1.删除哪个表的数据?--》表名
2.删除哪些行?--查询条件
--》语法
delete from 表名 [where 查询条件];
备注:如果不交条件,删除的是整个表的数据 ;--慎重使用
建议:先查询再删除,做数据备份
select * from emp where ename='SUN2';
delete from emp where ename='SUN2';
commit;
--------------------update 语句-------------------------
功能:修改数据:将原来的数据改成另一个数据:将空值改成有值;将原来的值改成另外一个值;将有值改成空值
想清楚:
1.修改哪个表的数据;--》表名;
2.修改哪个列的数据?把数据修改为什么? --》列名,新值
3.修改哪些行的?--where 查询条件
update 表名 set 列名1=新值,列名2=新的值,... [where 查询条件];
补充: = 两个功能
1.查询条件中,是精确查询的运算符;不可以和 null 一起使用;
2.在 update 语句中,set 后面,= 用来进行赋值; 可以和 null 一起使用。
例如:修改司马懿的手机号码为空值;
update user_tab set phone=null where user_name='司马懿';
select * from user_tab;
练习:
1.查询出你插入的新入职的职工信息;
select * from emp where ename='SUN2'
2.修改职工信息中空值为非空状态,非空值改成空值状态;
3.rollback;
4.再次修改职工信息,将薪水提升500;
update emp set sal=nvl(sal,0)+500 where ename='SUN2';
update emp set sal=500 where ename='SUN2';
5.commit;
6.删除其中一个职工信息;
7.rollback;
请问:最后该职工的信息如何?
-------------------------------------------------------------------------------------
DDL:数据定义语言
三个语句
create 语句:创建对象的,例如;创建表
alter 语句:改变并修改对象的,例如:修改表
drop 语句:删除对象的,例如:删除表
工作中:需求--》开发:设计(界面设置,功能设计,数据库设计)--》写代码,用到数据《——创建数据库、创建表:DDL--》DML-->DQL
测试:计划、方案、用例... -->执行测试(DQL、DML)
----------------------------------create 语句------------------
表:由列来组成;
想清楚:
1.这个表用来存放什么数据;--确定列
2.起名字:表名,列名(不要中文,不要特殊字符,符合编码规范)
同一个数据库中,表名不得重复;
同一个表中,列名不得重复。
--》语法
create table 表名(
列名1 数据类型(size),
列名2 数据类型(size),
...
列名3 date);
例如:创建一个药品信息表:确定列:药品编号、药品名称、药品生产厂家、生产日期...等等;
create table yp(
yp_bh number(5),
yp_mc varchar2(50),
yp_sccj varchar2(100),
yp_scrq date);
desc 表名 ; --describe 描述,功能:查看表结构,即,查看表中列的信息;
desc yp;
-----------------------------------alter 改变表,修改表
修改:1.给表添加列 ;2.修改列信息;3.删除列
----加列
alter table 表名 add(
列名 数据类型(size),
列名2 数据类型);
例如:给yp表添加价格,数量以及药品保质期三个列;
alter table yp add(
yp_jg number(5,2),
yp_num number(4),
yp_bzq date);
-- 改列:一般都是用来扩充列的取值范围
alter table 表名 modify(
列名 数据类型(size),
列名2 数据类型(size));
desc t0307_4;
alter table t0307_4 modify(num number(8));
insert into t0307_4 values(2342343.34563563563567);
select * from t0307_4;
-- 删除表中的列
alter table 表名 drop(列名,列名2,...);
例如:删除药品表中厂家和保质期两列
desc yp;
alter table yp drop(yp_sccj,yp_bzq);
-----------------------------drop 删除表
drop table 表名;
例如:删除yp表
drop table yp;
--------------------------------------------约束(了解)---------------------------
约束:功能:用来限制什么样的数据可以进入表中,什么样的数据不能进入;约束会直接影响DML语句的执行;
5种常见的约束:非空约束、唯一约束、主键约束、检查约束、外键约束(完整性约束)
约束全部都是添加在列上面的;约束建议创建表的时候添加
一、非空约束:如果有一列添加了非空约束,那么这一列的值不可以为空值 null ;即,空值进不去的
例如:创建一个公民信息表:身份证号,姓名,年龄,性别,手机号
drop table human;
create table human(
id char(18),
name varchar2(30) not null,
age number(3),
sex char(2),
phone char(11));
desc human;
insert into human values('61062019851231006X',null,18,'男',13325475779);
insert into human values('61062019851231006X','李一男',null,null,13325475779);
select * from human;
二、唯一约束:如果有一列添加了唯一约束,那么这一列如果有值,这个值必须唯一,不能跟这一列其他值重复,但是可以为空值;即,这一列可以为空值,但是有值就必须唯一
drop table human;
create table human(
id char(18),
name varchar2(30),
age number(3),
sex char(2),
phone char(11),
unique(phone));
desc human;
insert into human values('61062019851231006X','李一男',18,'男',13325475778);
insert into human values('61062019851231006X','李一男',18,'男',NULL);
select * from human;
三、主键约束:是非空和唯一的集合
如果有一列添加了主键约束,那么这一列的值不能为空值,而且值必须唯一;
例如:身份证号、学号、工号、药品编号、商品编号等等...
每个表都要求有一个主键,而且这个主键一般都是编号,不会将名字作为主键。
drop table human;
create table human(
id char(18),
name varchar2(30),
age number(3),
sex char(2),
phone char(11),
primary key(id));
desc human;
insert into human values('610620198512310066','李一男',18,'男',13325475777);
insert into human values('610620198512310064','李一男',18,'男',NULL);
select * from human;
四、检查约束:自定义约束,由用的人来决定限制什么:通过检查条件来进行限制;符合检查条件,数据就可以进入,不符合就进不去。
检查条件:就跟查询条件一样来写: 列名 运算符 搜索值
例如:公民信息表给驾校用;对年龄是有限制:18~70之间可以考
age >=18 and age<=70 或者 age between 18 and 70
drop table human;
create table human(
id char(18),
name varchar2(30),
age number(3),
sex char(2),
phone char(11),
unique(phone),
primary key(id),
check(age between 18 and 70));
desc human;
insert into human values('610620198512310066','李一男',19,'男',13325475777);
insert into human values('610620198512310064','李一男',71,'男',NULL);
select * from human;
五、外键约束(完整性约束):涉及2个表:其中一个是父表,另外一个子表;有继承关系,有从属关系;
如果表中一列有外键约束,这个外键列的取值要先在父表中;即,子表中外键列的数据可以在父表中找到,数据一般都是编号
select * from emp; --子表
select * from dept; --父表
insert into dept values(13,'帅哥部','西安');
insert into emp values(1239,'SUN2',null,null,'12-12月-2018',null,null,13);
select * from emp where empno=1239;
==>语法
foreign key(子表列名) references 父表表名(父表列名) --子表列名和父表列名有可能不一样
第三天的内容:多表联合查询、分组查询、子查询
练习补充:
1.删除主外键关系表数据,先删除子表中的数据,再去删除父表数据,例如:练习四,4
2.创建表时,存在主外键关系的,先创建父表,否则,在创建子表的时候提示“字段不存在”;
今天内容:多表联合查询,分组查询,子查询(必须掌握)
了解:内连接,外连接,常见的数据库对象,补充几个函数
7个语句回顾:
select 语句: select * from 表名 [where 查询条件] order by 列名 排序方式,列名2 排序方式;
查询条件:列名 运算符 搜索值
DML:insert / update /delete , 打开事务,commit ; rollback; --提交之前才生效 ,操作对象:数据
DDL:create / alter /drop ,操作对象:数据库对象:表或者用户等等 ,自带提交,一键生效
------------------------------------------------------------------------
表介绍
select * from student;
--学生表:sid 学号、sname 姓名、ssex 性别、sage 年龄、sphone 手机号、did 所在系的编号
select * from department;
--系别表:did 系的编号、dname 系的名称、dphone 系办电话;
select * from course;
--课程表: cid课程的编号、cname课程的名称、chour课时、tname 讲课老师
select * from score;
--选课分数表score:scid 选课编号、sid学号、cid课程编号、grade 成绩
关系:
1.一对一的关系:例如:学号和学生的关系,课程编号和课程也是一对一,一个学号只能确定一个学生(数据库表中,通过主键约束体现)
2.一对多的关系:例如:系别和学生的关系,一个学生只能归属于一个院系,但是一个院系会有很多个学生,从属关系(数据库表中,通过外键约束)
3.多对多的关系:例如:课程和学生,一个课程可以被很多学生选;一个学生也可以选很多课程,(在数据库表中,需要第三个表来体现,score)
---------- 多表联合查询
例如:查询学生的姓名,性别,以及这个学生所在院系的名称?
select * from student;
select * from department;
select * from student,department where student.did=department.did;
select sname, ssex, dname,student.did from student,department where student.did=department.did;
select sname,ssex, d.dname,d.* from student s, department d where d.did= s.did;
例如:查询学生的姓名,年龄,这个学生选的课程的名称,以及这门课考试的分数;
select * from student,course,score where student.sid=score.sid and score.cid = course.cid;
select sname,sage, cname, grade,student.sid
from student,course,score
where student.sid=score.sid and score.cid = course.cid;
----总结
1.多表联合查询:你想要的数据在多个表中,得从多个表中查询获取自己想要的数据,但是必须要加连接条件,如果不加,会出现大量的错误数据;
2.连接条件:先分析表跟表之间的关系,即:数据跟数据之间的关系;把关系变成了SQL条件写出来即可,表跟表之间的关系一般是主外键关系,但是有特殊
3.一个连接条件只能连接2个表;如果连接N个表,至少需要N-1个条件;
==》语法:
select * from 表名,表名2,表名3,... where 1个或者多个连接条件 [and 查询条件];
查询内容:全部信息 、 部分列(, 分隔)、某个表的全部列: 表名.*;
如果涉及表比较多,可以给表起别名,注意查询内容及连接条件中明确定义列需要用别名;
例如:查询学生的姓名,年龄,这个学生选的课程的名称,以及这门课考试的分数;只保留成绩高于80 分的学生信息
select sname,sage, cname, grade,s.sid
from student s,course c,score s2
where s.sid=s2.sid and s2.cid = c.cid and grade>=80;
select sname ,sage,cname,grade ,s.sid from student s,course c,score s2
where s.sid=s2.sid and s2.cid=c.cid and grade>=90;
练习:
emp dept
1. 查询员工的姓名、岗位、薪水、以及员工所在部门的名称、地点
select * from emp;
select * from dept;
select ename,job,sal, dname, loc, emp.deptno from emp,dept where emp.deptno=dept.deptno;
emp dept
2. 查询员工的所有列,以及员工所在部门的名称
select emp.*, dname from emp ,dept where emp.deptno=dept.deptno;
select emp.*,dname from emp ,dept where emp.deptno=dept.deptno;
student、course、score、department
3.查询学生的姓名、选的课程的名称、课时、这门课考试的分数,以及这个学生所在系的名称
select sname,cname,chour,grade,dname
from student s,course c,score s2,department d
where s.sid=s2.sid and c.cid=s2.cid and s.did=d.did;
4. 查询计算机系的学生的姓名、选的课程的名称、课时、这门课考试的分数,以及这个学生所在系的名称
select sname,cname,chour,grade,dname
from student s,course c ,score s2 ,department d
where s.sid=s2.sid and c.cid=s2.cid and d.did=s.did and d.dname='计算机';
----特殊情况:有的表不是主外键关系,而且列名不一样,也可以一样写多表联合查询
例如:查询职工的姓名,薪水,以及薪水所在级别?
select * from emp;
select * from salgrade;
关系:薪水>=某级别最低薪水 并且 薪水<=某级别最高薪水,薪水在该级别范围之内,就认为属于该级别
SQL: sal>=losal and sal<=hisal 或者 sal between losal and hisal
select ename,sal, grade from emp,salgrade where sal between losal and hisal;
select ename,sal,grade from emp, salgrade where sal between losal and hisal;
----------- 分组查询
分组查询主要是用来做统计的,一般都是按照某个列进行统计;
统计类型包括:求和,求最大,最小,求平均...
分组查询需要结合分组函数一起使用;
count(参数):统计查询语句返回的行数;
max(参数):求最大
min(参数):最小的
avg(参数):求平均
sum(参数):求和
参数一般都是列名,当参数是列名时,会过滤掉该列为空值的数据
例如:查询员工信息表中所有信息,然后统计公司员工你的人数,公司的平均薪水,公司最高薪水,公司的最低薪水
select count(*),count(1),count(sal),avg(sal),sum(sal)/count(*),max(sal),min(sal) from emp where sal is not null;
insert into emp values(3456,'sunsun',null,null,null,null,null,30);
select count(*),count(1),count(sal),avg(sal),sum(sal)/count(sal),max(sal),min(sal) from emp;
select * from emp;
2个数值处理函数:
round(参数1,参数2): 四舍五入,参数1,表示需要处理原数值, 参数2>0,小数点向右;<0,小数点向左;=0,小数点位置
trunc(参数1,参数2):直接截取,参数1,表示需要处理原数值, 参数2>0,小数点向右;<0,小数点向左;=0,小数点位置
select count(*),count(1),count(sal),trunc(avg(sal),3),sum(sal)/count(*),max(sal),min(sal)
from emp
where sal is not null;
select trunc(avg(sal),2) from emp;
dual 虚表
表中没有实际的数据,主要是用来做一些跟表数据无关的查询;比如:数值转换、转换字符、查询系统时间,做运算
select trunc(654356.3456356345,-2) from dual;
select trunc(236.7878,-2)from dual;
select sysdate from dual;
select sysdate from dual;
select 4567*5647 from dual;
select 888*2 from dual;
例如:统计部门编号为10的员工人数信息,这个部门的平均薪水;
select count(*),avg(sal) from emp where deptno=10;
例如:统计每个部门的员工人数,以及该部门的平均薪水;即:按照部门编号统计人数和平均薪水==》按照部门进行分组,然后统计该部门的信息
select count(*),avg(sal) from emp where deptno=10;--3
select count(*),avg(sal) from emp where deptno=20; --7
select count(*),avg(sal) from emp where deptno=30; --8
按照部门编号进行分组,统计每个部门的人数和平均薪水;
select count(*),round(avg(sal),2), deptno from emp group by deptno ;
按照部门编号先分组,再按照每个部门的岗位进行分组,统计每个部门各个岗位的人数和平均薪水;
select count(*),round(avg(sal),2), deptno,job from emp group by deptno ,job order by deptno;
select count(*),round(avg(sal),2),deptno,job from emp group by deptno,job order by deptno;
按照部门编号进行分组,统计每个部门的人数和平均薪水,只保留人数超过3个人的部门信息;
select count(*),round(avg(sal),2), deptno from emp group by deptno having count(*)>3;
----分组查询总结
关键字:
按照** 分组:group by 列名
分组之后进行数据过滤:having 过滤条件(查询一条)
==》语法
select 分组函数,被分组的列名 from 表名(1个或者多个) group by 列名,列名2,... [having 过滤条件];
例如:按照部门名称统计分析每个部门的人数和平均薪水;
select count(*),avg(sal), dname from emp,dept where emp.deptno=dept.deptno group by dname;
select * from emp;
select * from dept;
student
1. 按照系别编号统计,每个系的学生人数,学生的平均年龄,学生最大年龄
select * from student;
select count(*),avg(sage),max(sage),did from student group by did order by did asc;
2. 按照性别去统计,统计每个性别的人数,性别最小年龄
select ssex,count(*),min(sage) from student group by ssex;
3. 按照系别编号和性别一起去分组,统计每个系的男的多少人,女的多少人
select count(*),did,ssex from student group by did,ssex order by did;
--------------- 子查询
子查询:又叫做嵌套查询;一个语句里面包含了查询语句;想要的数据不是直接可以查询出来,查询过程需要拐个弯
常见子查询用法:1.子查询用在查询条件当中;(重点关注)
2.子查询用来代替一个表
一、子查询用在查询条件中;子查询代替一个值:搜索值
例如:查询年龄比金小子大的学生信息;
select sage from student where sname='金小子'; --sage=20
select * from student where sage>20;
--等价替换
select * from student where sage>(select sage from student where sname='金小子');
步骤:先分步后合并
a.先查询出金小子的年龄;
b.找出比 a 大的学生信息;
c.合并,等价替换
==》语法:
select * from 表名 where 列名 运算符 (子查询语句);
delete from 表名 where 列名 运算符 (子查询语句);
例如:删除比金小子年龄大的学生信息;
select * from student where sage>(select sage from student where sname='金小子');
delete from student where sage>(select sage from student where sname='金小子'); -->报错了,违法完整性约束,有同学选课考试了
练习:
1. 查询性别跟“叶玉娟”不一样的学生
select * from student where not(ssex=(select ssex from student where sname='叶玉娟'));
2. 查询计算机系的学生信息
select did from department where dname='计算机';
select * from student where did=(select did from department where dname='计算机');
select * from student where did=(select did from department where dname='计算机') or did=(select did from department where dname='数学');
select * from student where did in(select did from department where dname in('计算机','数学'));
select * from student where did=any(select did from department where dname ='计算机' or dname='数学');
3. 查询年龄比学生平均年龄大的学生
select * from student where sage>(select avg(sage) from student );
----总结,子查询的使用原则
1.子查询一定要放在小括号中;
2.子查询语句放在查询条件的右侧;
3.子查询分为单行子查询,多行子查询
单行子查询:子查询语句返回的行数是一行;一个值(一个列);
多行子查询:子查询语句返回的是多行; 多个值 (一个列)。
单行子查询的运算符:=,!=,>,<,>=,<=
多行子查询的运算符: in any all
all / any 需要结合=,>=,<=,>,< 等一起使用
all :跟子查询返回的所有值进行比较,比赢所有值;
any :跟子查询返回的所有值进行比较,比赢其中一个即可;
>all(子查询):大于最大的 <all(子查询):小于最小的
>any(子查询):大于最小的 <any(子查询):小于最大的
例如:查询年龄比金小子,叶玉娟,王五都要大的学生信息;
单行子查询:
select * from student where sage>(select max(sage) from student where sname in('金小子','叶玉娟','王五'));
多行子查询:
select * from student where sage>all(select sage from student where sname in('金小子','叶玉娟','王五'));
二、子查询来代替一个表:主要是用在TOP-N分析中
TOP-N 分析需要结合:子查询、排序、伪列(rownum)一起使用
伪列:不是表中实际存在的列,但是都可以使用,主要是用来查询表中前多少行数据的;运算符 <,<=
例如:查询学生表中前3个学生信息
select * from student where rownum<=3;
查询职工表中前5位职工信息;
select * from emp where rownum<=5;
例如:查询职工薪水收入在前5位的员工信息;
select * from emp order by sal desc; --当做aa表
select * from aa where rownum<=5;
----等价替换
select * from (select * from emp order by sal desc) where rownum<=5;
课后练习:9. 查询薪水第6~第10的员工信息;
select * from emp order by sal desc
select * from (select * from emp order by sal desc) where rownum<=10;
综合练习:
emp、dept
1. 查询统计部门和销售部门的员工信息
select * from emp;
select * from dept;
select * from emp e,dept d where e.deptno=d.deptno and dname='ACCOUNTING' or dname ='SALES';
select * from emp e,dept d where e.deptno=d.deptno and dname in('ACCOUNTING' ,'SALES');
select * from emp e,dept d where e.deptno=d.deptno and dname in('ACCOUNTING' ,'SALES');
2. 查询薪水比每个部门平均薪水都要高的员工信息 ---分组查询、子查询
select * from emp;
select * from dept;
select avg(sal) from emp group by deptno;
select * from emp where sal>(select max(avg(sal)) from emp group by deptno);
3. 按照部门名称去统计每个部门的人数,平均薪水 ---分组查询、多表联合查询
select * from emp e, dept d where e.deptno=d.deptno
select dname, count(*),avg(sal) from (select * from emp e, dept d where e.deptno=d.deptno)group by dname
student、score、course
4. 查询王五这个学生选的课程的名称,课时,和讲课老师 ---子查询
select * from course;
select * from student where sname='王五'; -- sid=10001,did=1001
select * from score;
select cid from score where sid=10001;
select cname,chour,tname from course where cid in (select cid from score where sid =(select sid from student where sname='王五'))
/*
SCH01
SCH05
SCH03
SCH02
*/
select * from course where cid in(select cid from score where sid=(select sid from student where sname='王五'));
select cname,chour,tname from course where cid in(
select cid from score where sid=(
select sid from student where sname='王五'));
select cname,chour,tname from student s,course c,score s2 where s2.sid=s.sid and s2.cid=c.cid and sname='王五';
---------------------- 了解的
5个分组函数
2个数值处理函数
1个空值函数
2个日期转换函数
5个字符处理函数
5个字符处理函数:
lower(参数):将所有字母小写
upper(参数):将所有的字母大写
initcap(参数):将每个单词的首字母大写,其余小写
length(参数):求字符串长度
参数:可以字符类型的列名,也可以是一个普通的字符串
substr(参数1,参数2,参数3):取子串
参数1:待处理的原数据
参数2:从第几位开始截取
参数3:截取几位,截取的长度
例如:查询员工的姓名,岗位,要求姓名全部小写
select ename,lower(ename),job from emp;
普通字符串:
'HELlo wOrLd!'
select lower('HELlo wOrLd!'),upper('HELlo wOrLd!'),initcap('HELlo wOrLd!'),length('HELlo wOrLd!'),substr('HELlo wOrLd!',2,6) from dual;
-----------------------------常见的数据库对象
表(table ):由行和列一起组成的二维表格;行又叫做记录 , 列 又叫做属性(字段)
视图(view):用来简化查询语句的;可以让一个复杂的查询语句变得简单...
select cname,chour,tname from course where cid in(
select cid from score where sid=(
select sid from student where sname='王五'));
create view v0722 as select cname,chour,tname from course where cid in(
select cid from score where sid=(
select sid from student where sname='王五'));
select * from v0722;
备份表:create table 表名 as select 语句;
create table emp2 as select cname,chour,tname from course where cid in(
select cid from score where sid=(
select sid from student where sname='王五'));
索引(index):提高查询效率的;如果有索引,可以查询的快一些,主要是用在数据量特别大的情况下才有效果;
但是,索引不可以创建很多,因为会大量占用表空间。
select * from student where sphone='18183929384';
create index id0722 on student(sphone);
存储过程:数据库中进行编程,数据库中写代码(procedure),可以将业务逻辑,规则,方法写成存储过程或者函数保存在数据库中,方便其他模块调用,
从而简化应用程序的开发。
create [or replace] procedure 存储过程名称
(
[arg1 [IN|OUT|IN OUT]] 数据类型,
[arg2 [IN|OUT|IN OUT]] 数据类型,
...
)
is|as
声明部分;
begin
执行部分;
exception
异常处理部分;
end;
--------------------------- 内连接、外连接
内连接:多表联合查询的另外一种写法
关键字:inner join ... on...
例如:select * from emp,dept where emp.deptno=dept.deptno;
select * from emp inner join dept ON emp.deptno=dept.deptno;
外连接:并非主外键关系
左外连接:left outer join ... ;先将符合连接条件的数据查询出来,再将左表中不符合条件的数据查询出来;右表满足条件的+左表全部
右外连接:right outer join ...;先将符合连接条件的数据查询出来,再将右表中不符合条件的数据查询出来;左表满足的+右表全部
全外连接:full outer join ...; 先将符合连接条件的数据查询出来,再将左表中不符合条件的数据查询出来,再将右表中不符合条件的数据查询出来
查询外键名称,约束表,约束列,参照表,参照列,删除级联,后面跟上需要查询的表的名称。
select b.constraint_name, b.table_name, b.column_name,c.table_name as,c.column_name ,a.delete_rule
from user_constraints a
left join user_cons_columns b on a.constraint_name = b.constraint_name
left join user_cons_columns c on a.r_constraint_name = c.constraint_name
where a.constraint_type = 'R' and a.table_name = 'EMP'