系统开始学后端Java相关

sql多表查询

2019-04-19  本文已影响0人  DeeJay_Y

sql会创建多表以及多表的关系

需求:

上篇文章中的商品表和分类表之间存在着所属关系,在数据库如何表示这种关系

分析:

多表之间的关系如何来维护

添加外键约束之后,如果想删除category中的某一列,也会报错,因为product中有记录在引用。首先得去product表中删除引用该种类的所有记录,才能去删除category中的相应列。

建立数据库的原则

通常情况下,一个应用一个数据库。

多表之间的建表原则

一对多

例子中提到的product和category就是一对多的关系,一个种类对应多个商品

多对多

例如:老师和学生,学生和课程等
student表 id name gender age
subject表 id name teacher
student表中的学生选了不固定的subject表里的科目,这种关系为多对多

一对一

例如公民和身份证的关系:
People表: id name income
IDcard表:sid 头像 性别

实际用途不多,比如说拆表操作(将表中的一些列拆分出来)

关于主键约束和唯一约束的区别:
主键约束:默认不能为空且唯一,并且不能有多个主键
唯一约束:默认为空且唯一,可以有多个唯一约束键
外键都是指向另一张表的主键,而唯一的约束不可以作为其他表的外键

多表查询

在一个商城应用中,有几个表之前的数据相互关联:user表 order表 product表 category表 以及orderItem表

多表查询的几种类型:

select * from product,category;
笛卡尔积

上述例子中查出来的结果称为笛卡尔积即2张表的乘积,没什么实际意义。其实我们需要的就是cno等于cid的那些数据,所以需要做一下过滤。

select * from  product,category where cno=cid;

对于上述查询,经常会发现cno和cid属于哪个表不明确,可以通过起个别名的方式来指明是哪个表: select * from product as P,category as C where p.cno=c.cid;

上述2种方式查询出来的结果都是一样的,但是区别在于,隐式内连接是在查询出的结果基础上进行的where条件过滤,但是显式内连接是带着条件去查询结果的,执行效率是比较高的

insert into product values(null, "一条没有cno的记录", 100, null, null);

然后执行左外连接查询:

select * from product p left join category c on p.cno=c.cid;

可以看到右表的这一条的输出都为null,而左表的数据都输出了。

left join和right join分别为left outer join和right outer join的缩写 inner/outer在语句中可以省略

简单理解: 内连接查出来的是2个表的交集,左外和右外其实查询了左表或者右表的全部,并且如果有相对应的左表记录的话也会显示。

通过union连接的SQL它们分别单独取出的列数必须相同;不要求合并的表列名称相同时,以第一个sql 表列名为准;使用union 时,完全相等的行,将会被合并,由于合并比较耗时,一般不直接使用 union 进行合并,而是通常采用union all 进行合并;

被union 连接的sql 子句,单个子句中不用写order by ,因为不会有排序的效果。但可以对最终的结果集进行排序;
(select id,name from A order by id) union all (select id,name from B order by id); //没有排序效果
(select id,name from A ) union all (select id,name from B ) order by id; //有排序效果

分页查询(使用limit)

假设规定pageSize为3

select * from product limit 0,3; // 第一页
select * from product limit 3,3; // 第二页
select * from product limit 6,3; // 第一页

即每次查询根据page和pageSize计算一个起始的索引位置即可:

select * from product limit (page-1)*pageSize,pageSize;

子查询

即sql语句中再嵌套sql语句

  1. 如果要查询分类名为“手机数码”的商品,需要动态查询出在category中的cid
select * from product where cno=(select cid from category where cname="手机数码");
  1. 如果要查询出商品名称(pname)和商品分类名称(cname)的信息
    选用左右链接查询都可达到目的,在这介绍下子查询的写法:
select pname,(select cname from category as c where p.cno=c.cid) from product as p;
上一篇下一篇

猜你喜欢

热点阅读