本篇博客讲解(子查询)非相关子查询/相关子查询,一对一,一对多,多对一,多对的的关系!
准备:
首先我们创建一列sex。再为部分行设置好值0(女)或者1(男);

delete from stud where age=26;
删除年龄为26的行。
1. update stud set sex='1' where saddress like '湖南%';
将地址中湖南开头的人的的sex修改为1。
1. update stud set sex='0' where age>=30 and sex is null;
将年龄大于等于30的,且性别为null的人的sex设置为0.
case-when then else end 语句.
现在要做这样一件事,查询显示的时候sex不显示0,1和null,我们让它0的就显示女,1的就显示男,null就显示未知。
这时我们需要用到:
case-when then else end 语句.
修改 * 当 * 时候 修改成 * 否则修改成 * END
when then 可以写多句
1. select sno,sname,age,saddress,(case sex when '0' then '女' when '1' then '男' else '未知' end) as 性别 from stud;
有人可能会有疑问,不是定义了sex只能有一个字符嘛,为什么还能用‘未知’啊,因为这里只是显示的,并不是存储到数据库中的数据,只是相当于输出字符。

子查询:
子查询:嵌套在其它查询中的查询语句。(又称为内部查询)
主查询:包含其它子查询的查询称为主查询。(又称外部查询)
非相关子查询:
在主查询中,子查询只需要执行一次,子查询结果不再变化,供主查询使用,这种查询方式称为非相关子查询。
也可以这么理解:
非相关子查询是独立于外部查询的子查询,子查询总共执行一次,执行完毕后将值传递给外部查询。

现在我们来对这个表做一个查询:
查询具有年龄相同的人在2人及以上的,他们的年龄分别是多少。
1. select age from stud group by age having count(age)>=2;

count(age)在这里只是作为供主查询使用的条件。
相关子查询:
相关子查询的执行依赖于外部查询的数据,外部查询执行一行,子查询就执行一次。
也可以这么理解:
执行查询的时候先取得外部查询的一个属性值,然后执行与此属性值相关的子查询,执行完毕后再取得外部父查询的下一个值,依次再来重复执行子查询;
我们先把表格增加一列sex并设置好值。

接下来:
查询不但具有年龄相同的人在2人及以上的,而且性别是1的那些人的年龄。
1. SELECT age,sex FROM stud GROUP BY age,sex HAVING COUNT(age)>=2 AND sex='1';
表与表之间的关系:
一对一:
需要两个表。当然做项目时为了省空间,通常只建一个表,如果要实现一对一的查询,可以建立两个视图。示例如下:
1)先建物理表,初始化数据、


2)建立两个视图
1. create view women as select * from person where sex='0';
2. create view men as select * from person where sex='1';
3)查询夫妻信息
92年以前是这样查询的:
1. select women.name as 妻子,men.name as 丈夫 from women,men where women.husband=men.id and women.id=men.wife;

一对多/多对一:
数据库设计分析:
案例:一个人可以拥有多辆汽车,要求查询出某人所拥有的所有汽车。
方案一:(差的设计-用一张表存储–数据冗余太严重)

方案二(好的设计):

2)把多方也建个表(依赖一方,通过外键–补一个字段)
外键:位于依赖一方,它是被依赖一方是主键

3)代码实现:


查询每个人拥有的车辆:
92年之前的写法:
1. select person2.sname as 车主,car.sname as 车辆 from person2,car where car.pid=person2.id;

现在的内关联写法:
1. select person2.sname as 车主 ,car.sname as 车辆 from person2 join car on car.pid=person2.id;

一对多和多对一是一样的!反过来理解就是了。
多对多:
数据库设计分析
案例:一个人可以选择多门课程,一门课程又可以被多人选择。
方案一:(差的设计–数据冗余太严重)
1)学生表

2)课程表

pass。
方案二(好的设计:两个实体表+一个关系表):
1)学生表(独立)—实体

2)课程表(独立)—实体

3)选课表(专为体现多对多的关系而新增的表)–关系

4) 代码实现

如果需要删除外键

初始化stud表数据


初始化ject表:


初始化sj表:


关联(也称为连接):
左关联(left join) 右关联(right join) 内关联(inner join)
mysql不支持: 全关联(full join) 外关联(outter join)
可以把关联理解成:几个表合成一个新的表,然后在新表中进行查询!
查询哪些人选了哪些课:
92年之前是这样查询的:(没有用关联)
1. select stud.sname,ject.sname from stud,sj,ject where stud.id=sj.studid and ject.id=sj.jectid;

用内关联来:

内关联可以这样来看,以中间的sj表为主表,来合另外2个表。

查询哪些人没有选课:
不用关联的写法:
1. select stud.sname from stud where stud.id not in(select studid from sj);

用左关联的写法:

左关联就是把左边的表作为主表,也就是说,stud必须是完整的,可以增加,但不能减少,再按照sj表的关系,来添加ject表的数据。

查询哪些课程没人选:
不用关联的写法:

用左关联的写法:

最后的那里也可以用stud.sname is null来判断。
但要注意,需要原来的stud表中的那个属性定义了not null。
否则会出现bug。

用右关联写:

左关联和右关联实质上是差不多的。认真的看下上面的左关联和右关联就可以看出来了。
---------------------
作者:谙忆
来源:CSDN
原文:https://blog.csdn.net/qq_26525215/article/details/52137140
版权声明:本文为博主原创文章,转载请附上博文链接!
网友评论