【数据库复习】数据库约束,往表中插入查询结果,查询(聚合查询,联合查询(内外连接图解))

数据库约束

  • NOT NULL:指定某列不能存储null值
  • UNIQUE (唯一约束):某列的信息不能重复但可以为null
  • DEFAULT (默认值约束):规定没有给列赋值时的默认值
    – 指定插入数据时,如果name为空,默认值设置为‘unkown’
DROP TABLE IF EXISTS student;
CREATE TABLE student (
   id INT NOT NULL,
   sn INT UNIQUE,
   name VARCHAR(20) DEFAULT 'unkown',
   qq_mail VARCHAR(20)
);
  • PRIMARY KEY (主键约束):相当于not null 和 unique的结合。某列的信息不能重复也不能为null
    – 指定id为主键
DROP TABLE IF EXISTS student;
CREATE TABLE student (
   id INT NOT NULL PRIMARY KEY,
   sn INT UNIQUE,
   name VARCHAR(20) DEFAULT 'unkown',
   qq_mail VARCHAR(20)
);

又因为主键就是唯一且不能为空,是 not null 和 unique 的结合,所以此处可以将not null去掉

   id INT PRIMARY KEY,
  • FOREIGN KEY (外键约束):保证一个表中的数据匹配到另一个表的值的参照完整性
    外键是用于关联其他表的主键或唯一键
foreign key (字段名) references 主表(列)

【例】
比如说此处再创建一个班级表,id设置为主键

DROP TABLE IF EXITS classes;
CREATE TABLE classes(
	id INT PRIMARY KEY,
	name VARCHAR(20),
);

学生表中使用id为主键,classes_id为外键,关联班级表中的id

DROP TABLE IF EXISTS student;
CREATE TABLE student (
   id INT PRIMARY KEY,
   sn INT UNIQUE,
   name VARCHAR(20) DEFAULT 'unkown',
   qq_mail VARCHAR(20)
   classes_id INTFOREIGN KEY (classes_id) REFERENCES classes(id)
);
  • CHECK约束
drop table if exists test_user;
create table test_user (
   id int,
   name varchar(20),
   sex varchar(1),
   check (sex ='男' or sex='女')
   -- 所以此处性别只能填男或者女,其他会报错,这就是check约束
);

新增 (此处是指插入查询结果)

INSERT INTO table_name [(column[,column...])] SELECT ...

【例】 比如说原来有一张表student(里面的字段有name,qq_mail),现在新建了一张表test_user(里面字段有name,email,sex,mobile),需要把之前student表中的数据复制过来

INSERT INTO test_user (name,emil) select name,qq_mail from student;

查询

1. 聚合查询

① 聚合函数
  • COUNT 返回查询到的数据的数量
-- 统计班上一共有多少同学
SELECT COUNT(*) FROM student;
SELECT COUNT(0) FROM student;
--统计班上收集的qq_mail有多少条(为null的不会计算进去哦)
SELECT COUNT(qq_mail) FROM student;
  • SUM 返回查询到的数据的总和,一般都使用在数字类型上,不是数字没有意义
-- 统计同学们数学总分
SELECT SUM(math) FROM  exam_result;
-- 统计数学不及格的同学的数学总分
SELECT SUM(math) FROM exam_result WHERE math<60;
  • AVG 返回查询到的数据的平均值,一般都使用在数字类型上,不是数字没有意义
-- 统计班上同学的平均总分
SELECT AVG(chinese+math+english) AS average_score FROM exam_result;
  • MAX 返回查询到的数据的最大值,一般都使用在数字类型上,不是数字没有意义
-- 返回班上数学最高分
SELECT MAX(math) FROM exam_result;
  • MIN 返回查询到的数据的最小值,一般都使用在数字类型上,不是数字没有意义
-- 数学及格的数学最低分
SELECT MIN(math) FROM exam_result WHERE math > 60;
② GROUP BY

group by子句可以对指定列进行分组查询,但是需要满足:使用group by进行分组查询时,select指定的字段必须是分组所依据的字段,如果是非分组依据字段想要出现在select中则必须包含在聚合函数当中

SELECT column1,SUM(column2) FROM table_name GROUP BY column1,column3;

在这里插入图片描述
==【例】==查询classes表(有课程号cid,课程名cname,分数score)中各科目的最高分,最低分,平均分

SELECT cname,MAX(score),MIN(score),AVG(score) FROM classes GROUP BY cname;
③ HAVING

如果用了GROUP BY子句进行了分组之后,需要对分组结果再进行过滤时,不可以在使用WHERE语句,而是要用HAVING
==【例】==显示平均分低于60的科目和他的平均分

SELECT cname,AVG(score) FROM classes GROUP BY cname WHERE AVG(score)<60;

2. 联合查询

比如说现在有两张表table1,table2,table1中含有a,b,c三个字段,table2中含有c,d两个字段
table1:

abc
a1b1c1
a2b2c2

table2 :

cd
c1d1
c3d3
① 交叉连接(笛卡尔积) cross join
select 字段 from1 [别名1] ,2 [别名2];
select 字段 from1 [别名1] cross join2 [别名2];

没有任何关联条件,实际结果就是笛卡尔积,结果集会很大,没有意义,很少使用
结果表的行数是两表行数相乘

select * from table1,table2;
select * from table1 cross join table2;
abccd
a1b1c1c1d1
a1b1c1c3d3
a2b2c2c1d1
a2b2c2c3d3
② 内连接inner join

inner join 可以写成join
显示的是表1表2交叉重合的部分

select 字段 from1 别名1 [inner] join2 别名2 on 连接条件1 [and 连接条件2];
select 字段 from1 别名1,表2 别名2 where 连接条件1 [and 连接条件2];
select * from table1 t1 inner join table2 t2 on t1.c<=>t2.c;
select * from table1 t1,table2 t2 where t1.c<=>t2.c;

在这里插入图片描述

abccd
a1b1c1c1d1
③ 外连接
  • 左外连接left join
-- 左外连接,表1完全显示
select 字段名  from 表名1 left join 表名2 on 连接条件;
select * from table1 t1 left join table2 t2 on t1.c<=>t2.c;

在这里插入图片描述

abccd
a1b1c1c1d1
a2b2c2
  • 右外连接right join
-- 右外连接,表2完全显示
select 字段 from 表名1 right join 表名2 on 连接条件;

在这里插入图片描述

abccd
a1b1c1c1d1
c3d3
④ 自连接

自连接作为内连接的一种特例,可以将一个表与它自身进行连接,称为自连接。若要在一个表中查找具有相同列值的行,则可以使用自连接。使用自连接时需为表指定两个别名,且对所有列的引用均要用别名限定。
比如说有个学生成绩表(score),里面包含字段学号id,课程名cname,课程成绩sco,查询成绩表中英语成绩高于数学成绩的信息

	select * from score s1 
	inner join score s2 
	on s1.id = s2.id 
	and s1.sco<s2.sco 
	and s1.cname = 'math' 
	and s2.cname = 'english';
⑤ 子查询(嵌套查询)

嵌入在其他sql语句中的select语句

  • 单行子查询:返回一行记录的子查询
    ==【例】==在student表中查询‘chen’的同班同学
select * from student where class_id = 
	(select class_id from student where name = 'chen');
  • 多行子查询:返回多行记录的子查询
    ==【例】==查询math 或 english课程的成绩信息(score表中包含字段课程号cid,学生学号sid,成绩sco;课程表中包含字段课程号id,name)
  1. [NOT] IN
select * from score where cid in 
		(select id from course where name='math' or name='english');
  1. [NOT] EXISTS
select * from score s where exists 
		(select s.cid from course c where 
				(name ='math' or name = 'english') and s.cid = s.id);
  • 在from子句当中使用子查询:子查询语句出现在from子句中,将子查询的结果当作一个临时表使用
    ==【例】==查询所有比‘计卓1702班’平均分高的成绩信息
    step1:先查询‘计卓1702班’的平均分,将其看作临时表
select 
	avg(score.sco) sco 
from 
	score s 
	join student stu on s.sid = stu.id
	join classes c on stu.cid = c.id
where
	c.name = '计卓1702班';

steo2: 将上面的结果当作一个临时表

select
	* 
from
	score s,	
	(select 
		avg(score.sco) sco 
	from 
		score s 
		join student stu on s.sid = stu.id
		join classes c on stu.cid = c.id
	where
		c.name = '计卓1702班';
	)tmp
where 
	s.sco > tmp.sco;	
⑥ 合并查询

合并多个select的执行结果,可以用UNION , UNION ALL。使用的时候需要注意UNION和UNION ALL使用时前后查询的结果集中,字段需一致
注意:UNION 和 UNION ALL都是取得两个结果集的并集。前者会自动去掉结果集中的重复行,后者不会去掉结果集中的重复行
==【例】==查询id<3,或者名字为’english‘的课程

  • UNION
select * from course where id<3
union
select * from course where name='english';

相当于

select * from course where id<3 or name='english';
  • UNION ALL
-- 结果集中会出现重复的数据
select * from course where id<3
union all
select * from course where name='english';
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值