Mysql:sql语句(3)

上篇文章我们着重讨论了对于单表的操作,这次,我们将要讨论面临多表的情况,多个表之间可以有什么关系,当我们查询时遇到多个表应该如何操作等等,那么就让我们开始吧。

数据库约束

有时候,数据库中的数据,是有一定要求的,有些数据是合法数据,有些是非法数据,我们可以通过mysql提供的约束来对这些数据进行编辑。

MySQL提供以下约束:

not null 表示某列不能存储null值

unique 表示某列的每行必须有唯一的值

default 规定没有给列赋值时的默认值

primary key 主键,可以理解为not null 和 unique 的结合。确保某列有唯一标识,有助于更容易更快速地找到表中一个特定的记录。

foreign key 外键,保证一个表中的数据匹配另一个表中的值的参照完整性。

check 保证列中的所有值符合指定条件。

主键

一张表里只能有一个主键(primary key),也就是只能有一个作为身份标识的数据。虽然只能有一个主键,但主键不一定只能是一列,主键也可以由多个列一起构成。那么我们可以在创建表时指定主键:

creat table student(

id int primary key,

class

);

这样我们就成功的设置了主键。

为保证主键唯一,mysql提供了一种自增主键的机制,主键经常使用int。插入数据时,我们可以不必指定主键,而由数据库主动分配一个主键,会从1开始,依次递增分配主键的值,我们可以这样操作:

creat table student(

id int primary key auto_increament,

class

);

此时id这一列会交给mysql自动分配,插入时null就可以了。

当然,这种方法有一定局限性,如果是分布式系统,有多个mysql服务器构成的集群,结果可能就不尽如人意了。

外键

外键(foreign key)描述了两个表之间的关联关系。

我们先观察下面两个表

一个是班级表,一个是学生表学生的班级应该都是第一个班级表里的,所以下面这个学生表受上面这个班级表的约束。

(class int,foreign key(class))references class(id);

当我们在子表中执行插入操作时,会查询class表,如果将要修改的值已经被继承,那么修改将会失败。

进阶操作

增加:增加搭配查询使用

当我们增加数据时,我们可以把查询语句的查询结果,作为插入的数值。

举个例子,现在我们创建了一个新表student2,我们希望实现对student表的复制,那么再重新一个一个插入显然很麻烦,我们可以对student表进行全列查询,将结果作为数据填充至student2:

insert into student2 select* from student;

我们可以看到,我们成功的复制了出来,并且更加简便,更加方便我们操作。

查询:各种进阶查询

1.聚合查询

聚合查询,相当于行与行之间进行运算,我们可以通过聚合函数完成上述行之间的运算。

我们先介绍第一个聚合函数:count()

这个函数可以帮助我们返回查询到的数据的数量,简单来说就是返回查询的记录有几行。例如我们想统计目前学校有几个人,我们就可以理解为想查询student表中有几行记录,我们可以这样:

 select count(*) from student;

我们来深度讨论一下这句语句。首先,我们要先执行select * ,进行一个全列查询,之后针对全列查询查询到的结果,进行count()这个函数的操作,即对结果集合进行统计,看看具体有几行,并将查询到的结果返回。

count(*)得到的结果还可以参与各种算术运算,也可以搭配其他sql使用。

由此我们能得到,聚合函数可以实现行与行之间的运算,下面我们再介绍几个常用的聚合函数。

sum()

把这一列的若干行,进行求和,只针对数字类型使用,属于算术运算。

select sum(age) from student;

如上,我们算出了所有学生的年龄总和。(虽然没什么意义)

avg()

返回查询到的数据的平均值。

select avg(age) from student;

像这样我们可以算出学生的平均年龄,更加方便。

max()/min()

返回最大/最小值

这个应该很好理解,我们直接演示。

2.分组查询

下面我们来讨论分组查询。我们先来看一个表:(为了简便,我没有一个一个起名字,谅解一下)

这是一张关于学校职工的表,它显示了每个人的职位,有校长、教师、清洁工三类,并记录了他们每个人的工资。现在我们想统计一下平均工资,显然,将校长和老师的工资一起统计是没有意义的,他们的工资差别很大。我们最好的方法是将他们所有人按照职位分组,统计出校长、教师、清洁工每个职位的平均工资。

这里我们就要用到我们进行分组的语法,我们将要使用group by关键字,我们可以这样操作:

select role, avg(salary) from worker group by role;

我们可以发现,当我们使用group by函数时,它会将role这一列里相同的统计为一组,并进行类似于avg()这样的运算,这样就可以满足我们的要求。我们使用分组查询往往要搭配聚合查询(即聚合函数)进行计算,不然可能没有意义。

使用group by 可以搭配条件,需要区分是分组前的条件,还是分组后的条件。

分组前:用where写在group by 前面

分组后:用having写在group by后面

我们也可以同时使用,完成两类条件的筛选。

3.联合查询/多表查询

下面就进行我们的多表查询,我个人认为,难点在于进行对于两张或多张表的链接。下面,我们先了解一下表的笛卡尔积。我们先来看下面两张表,一张记录了学生的信息,一张记录了寝室的信息:

那么当我们什么都不加,直接暴力的链接两张表进行全列查询时,得到的结果就是两张表的笛卡尔积。

我们可以看到,两张表的每一行都进行了一个新的排列组合,student表的每一行与dorm表的每一行都进行了一个结合,这就是所谓的笛卡尔积。

显然,这并不是我们想要的结果,我们需要添加链接条件。我们发现,student记录了寝室信息,与dorm表是相对应的,那我们就可以进一步加入连接条件:

select * from student,dorm where student.dormno=dorm.dormno;

这样我们就添加了链接条件,得到了我们想用的表。student.dormno代表student表中dormno一列,而dorm.dormno代表dorm表中dormno一列。这就保证了当两个表的某一列列名相同时容易产生歧义和错误。

之后,我们就可以进行查询了,比如我们要查询张扬同学的信息,我们就添加条件,用and连接:

select * from student,dorm where student.dormno=dorm.dormno and sname="张扬";

最后,我们就可以对列进行精简,只保留我们想要的列。比如我们只是要查询联系电话和年龄:

这里我们建议查询时,保留的列也带上表名,这样不容易混淆,更加清楚。

以上就是我们多表查询的一般步骤,我们来总结一下:

(1)对多表进行笛卡尔积

(2)添加连接条件

(3)根据需求添加条件进行筛选

(4)针对列进行精简,只保留有需求的列

4.联合查询/自连接

自连接只需要用到一张表,一张表自己和自己笛卡尔积。

有时候我们需要进行行和行之间的比较,这时候我们可以使用自连接。

比如我们现在将要将dorm表进行自连接,我们可以这么操作:

select* from dorm as d1,dorm as d2;

这样可以将一张表自己与自己进行链接。需要注意,我们在连接时要将表用as起两个别名,不然sql会不知道你在干啥,链接不起来。

小结

到这里我们对数据的增删查改就全部讨论完了,这些都是对数据最基本的操作,大家务必掌握。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值