MySQL学习笔记四

本文详细介绍了SQL中的内连接(inner join)和外连接(left join、right join),包括它们的使用方法和示例,如查询所有玩具商品、玩具和文具商品等。同时,还讲解了子查询的运用,以及如何通过子查询和连接查询解决实际问题,如找出购买特定商品的客户等。
摘要由CSDN通过智能技术生成

目录

多表连接查询--有两种

一、内连接--inner join...on...

把两张表连接起来,不做任何设定,得到的是笛卡尔积--inner join

把两张表连接起来,按照某个字段连接在一起--inner join ... on ...

把两张表连接起来,按照某个字段连接在一起,按要求查询--inner join ... on ... where ...

二、外连接-- left join...on... 或 right join...on...

子查询

整理

查询出所有的玩具商品

查询出所有的玩具商品和文具商品

练习:

三重嵌套子查询

一个where+一个子链接表

 子链接大表

内连接嵌套的另一种写法:


多表连接查询--有两种

一、内连接--inner join...on...

内连接是sql中连接查询的一种;按照在意义层面相同的两个字段,连接两个表;

表和表的连接是乘的关系,如果不对字段进行设定,则得到的是笛卡尔积。

把两张表连接起来,不做任何设定,得到的是笛卡尔积--inner join

select * from commodity inner join commoditytype;

把两张表连接起来,按照某个字段连接在一起--inner join ... on ...

select * from commodity inner join commoditytype on c_type=ct_id;

把两张表连接起来,按照某个字段连接在一起,按要求查询--inner join ... on ... where ...

查询所有的玩具商品,需要连接【商品表】和【商品类型表】,从【商品类型表】中找到玩具的id再从【商品表】中取出;相当于先把两个表连接起来得到一个“新”表,从“新”表中按照“新”表中有的字段进行where条件筛选

select * from commodity 
inner join commoditytype on c_type=ct_id 
where ct_name='玩具';

二、外连接-- left join...on... 或 right join...on...

select * table_name left join join_table on...; 将左表定义为主表,显示数据时以左表为准,主表有数据就显示,如果主表没数据就不显示即使副表有这些数据也不显示;主表有的数据一定会显示出来,那么如果副表没有,mysql会用null来进行拼接;

select * table_name right join join_table on..

select * from commodity left join commoditytype on c_type=ct_id;
select * from commodity right join commodity on c_type=ct_id;

假设A、B是两个表也是两个集合,可以用集合的关系来理解内连接和外连接

A inner join B on .... ------  A∩B

A   left  join B on .... ------  A-B

A  right join B on .... ------  B-A

子查询

子查询就是查询语句的嵌套,把一个查询语句嵌套在where后,作为where的条件

查询结果为1个时,可以用=,查询结果为多个时,用in

select * from commodity 
where c_type=(select ct_id from commoditytype where ct_name='玩具');

select * from commodity 
where c_type in 
(select ct_id from commoditytype where ct_name='玩具' or ct_name='文具');

整理

查询出所有的玩具商品

#①
select ct_id from commoditytype where ct_name='玩具';
select * from commodity where c_type=1;
#子查询
select * from commodity 
where c_type=(select ct_id from commoditytype where ct_name='玩具');
#连接查询
select * from commodity inner join commoditytype on c_type=ct_id 
where ct_name='玩具';

查询出所有的玩具商品和文具商品

#①
select ct_id from commoditytype where ct_name='玩具' or ct_name='文具';
select * from commodity where c_type=1 or c_type=2;
#子查询
select * from commodity 
where c_type in 
(select ct_id from commoditytype where ct_name='玩具' or ct_name='文具');
#连接查询
select * from commodity inner join commoditytype on c_type=ct_id 
where ct_name='玩具' or ct_name='文具';

练习:

三重嵌套子查询

select c_name from commodity where c_id in 
(select o_cid from `order` where o_cuid in 
(select cu_id from customer where cu_name='刘德华'));

一个where+一个子链接表

select c_name from commodity where c_id in
(select o_cid from customer inner join `order` 
on cu_id=o_cuid where cu_name='刘德华');

 子链接大表

派生表需要给每个表取一个名字,取字段的时候要看是哪一张表的,a的还是c的?

#连接
select c.c_name from commodity as c 
inner join 
(select * from customer inner join `order` on cu_id=o_cuid) as a 
on c.c_id=a.o_cid;

#连接先取刘德华
select c.c_name from commodity as c 
inner join 
(select * from customer inner join `order` on cu_id=o_cuid where cu_name='刘德华') as a 
on c.c_id=a.o_cid;

#连接后取刘德华
select * from commodity as c 
inner join 
(select * from customer inner join `order` on cu_id=o_cuid ) as a 
on c.c_id=a.o_cid 
where a.cu_name='刘德华';

内连接嵌套的另一种写法:

连接字段的顺序乱没关系,但每个字段要点名出自于哪个表

 select *
 from commoditytype as ct, commodity as c,`order` as o,customer as cu
 where ct.ct_id=c.c_type and c.c_id=o.o_cid and o.o_cuid=cu.cu_id;

完成需求

select *
from commoditytype as ct, commodity as c,`order` as o,customer as cu
where ct.ct_id=c.c_type and c.c_id=o.o_cid and o.o_cuid=cu.cu_id and cu.cu_name='刘德华';

select c.c_name
from commoditytype as ct, commodity as c,`order` as o,customer as cu
where o.o_cuid=cu.cu_id and ct.ct_id=c.c_type and c.c_id=o.o_cid and cu.cu_name='张学友';

需求1:买过c_id=41号商品的有哪些人?

#单步查询
select o_cuid from `order` where o_cid=41;
select cu_name from customer where cu_id=o_cuid;

#子查询
select cu_name from customer where cu_id in (select o_cuid from `order` where o_cid=41);

#表连接查询
select cu.cu_name from customer as cu inner join (select * from commodity inner join `order` on c_id=o_cid) as a on cu.cu_id=a.o_cuid where o_cid=41;

#表连接查询二
select cu.cu_name
from customer as cu,`order` as o,commodity as c
where c.c_id=o.o_cid and o.o_cuid=cu.cu_id and o.o_cid=41;

需求2:买过c_id=41和c_id=22号商品的有哪些人?

分别查询出否买41和22有哪些人,利用内连接取交的特点形成新表;

查出买41的人o_cuid作为a表,查出买22的人o_cuid作为b表,inner join on把a和b连接起来,on的条件是两个o_cuid相等,即两个表中若出现了都相等的o_cuid,代表o_cuid为都买过41和22的人

mysql> select o_cuid from `order` where o_cid=22;
+--------+
| o_cuid |
+--------+
|      4 |
+--------+
1 row in set (0.00 sec)

mysql> select o_cuid from `order` where o_cid=41;
+--------+
| o_cuid |
+--------+
|      3 |
|      4 |
+--------+
2 rows in set (0.02 sec)

mysql> select * from
    -> (select o_cuid from `order` where o_cid=41) as a,
    -> (select o_cuid from `order` where o_cid=22) as b;
+--------+--------+
| o_cuid | o_cuid |
+--------+--------+
|      3 |      4 |
|      4 |      4 |
+--------+--------+
2 rows in set (0.02 sec)


mysql> select a.o_cuid from
    -> (select o_cuid from `order` where o_cid=41) as a,
    -> (select o_cuid from `order` where o_cid=22) as b
    -> where a.o_cuid=b.o_cuid
    -> ;
+--------+
| o_cuid |
+--------+
|      4 |
+--------+
1 row in set (0.00 sec)

其他写法

#内连接普通写法
select cu_name from customer where cu_id in
(
select a.o_cuid from 
(select o_cuid from `order` where o_cid=41) as a 
inner join 
(select o_cuid from `order` where o_cid=22) as b 
on a.o_cuid=b.o_cuid
);

#内连接另一种写法
select cu_name from customer where cu_id in 
(
select a.o_cuid from
(select o_cuid from `order` where o_cid=41) as a,
(select o_cuid from `order` where o_cid=22) as b 
where a.o_cuid=b.o_cuid
);

#查两遍,先查o_cid=22的o_cuid,从这里找到o_cid=41的a.o_cuid
select cu_name from customer where cu_id in
(
select a.o_cuid from (select o_cuid from `order` where o_cid=41) as a
where a.o_cuid in (select o_cuid from `order` where o_cid=22)
);

需求3:买过c_id=41或c_id=22号商品的有哪些人?

select cu_name from customer where cu_id in
(select o_cuid from `order` where o_cid=41 or o_cid=22);

需求4:有哪些商品从来没有被买过?

select c_id from commodity where c_id not in (select distinct o_cid from `order`);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值