2、from型子查询
(把内层的查询结果供外层再次查询)
#用子查询查出挂科两门及以上的同学的平均成绩
思路:
3、exists型子查询
(把外层查询结果拿到内层,看内层的查询是否成立)
三、union的用法
(把两次或多次的查询结果合并起来,要求查询的列数一致,推荐查询的对应的列类型一致,可以查询多张表,多次查询语句时如果列名不一样,则取第一次的列名!如果不同的语句中取出的行的每个列的值都一样,那么结果将自动会去重复,如果不想去重复则要加all来声明,即union all)
## 现有表a如下
id num
a 5
b 10
c 15
d 10
表b如下
id num
b 5
c 10
d 20
e 99
求两个表中id相同的和
select id,sum(num) from (select * from ta union select * from tb) as tmp group by id;
//以上查询结果在本例中的确能正确输出结果,但是,如果把tb中的b的值改为10以查询结果的b的值就是10了,因为ta中的b也是10,所以union后会被过滤掉一个重复的结果,这时就要用union all
select id,sum(num) from (select * from ta union all select * from tb) as tmp group by id;
#取第4、5栏目的商品,按栏目升序排列,每个栏目的商品价格降序排列,用union完成
select goods_id,goods_name,cat_id,shop_price from goods where cat_id=4 union select goods_id,goods_name,cat_id,shop_price from goods where cat_id=5 order by cat_id,shop_price desc;
【如果子句中有order by 需要用( ) 包起来,但是推荐在最后使用order by,即对最终合并后的结果来排序】
四、左连接,右连接,内连接
现有表a有10条数据,表b有8条数据,那么表a与表b的笛尔卡积是多少?
1、左连接
以左表为准,去右表找数据,如果没有匹配的数据,则以null补空位,所以输出结果数>=左表原数据数
语法:select n1,n2,n3 from ta left join tb on ta.n1= ta.n2 [这里on后面的表达式,不一定为=,也可以>,<等算术、逻辑运算符]【连接完成后,可以当成一张新表来看待,运用where等查询】
2、右连接
a left join b 等价于 b right join a
推荐使用左连接代替右连接
语法:select n1,n2,n3 from ta right join tb on ta.n1= ta.n2
3、内连接
查询结果是左右连接的交集,【即左右连接的结果去除null项后的并集(去除了重复项)】
mysql目前还不支持 外连接(即左右连接结果的并集,不去除null项)
语法:
#########
例:现有表a
name hot
a12
b10
c15
表b:
name hot
d12
e10
f 10
g8
表a左连接表b,查询hot相同的数据
查询结果:
name hot name hot
a12 d12
b10 e10
b10 f10
c15 null null
从上面可以看出,查询结果表a的列都存在,表b的数据只显示符合条件的项目
再如表b左连接表a,查询hot相同的数据
查询结果为:
name hot name hot
d12 a12
e10 b10
f10 b 10
g8 null null
再如表a右连接表b,查询hot相同的数据
查询结果和上面的b left join a一样
###练习,查询商品的名称,所属分类,所属品牌
理解:每一次连接之后的结果都可以看作是一张新表
###练习,现创建如下表
要求按下面样式打印2006-0601至2006-07-01期间的比赛结果
样式:
火箭 2:0 红牛 2006-06-11
查询语句为:
总结:可以对同一张表连接多次,以分别取多次数据。