子查询
子查询分为 标量子查询,列(级)子查询,行(级)子查询,表(级别)子查询,前两种较为常见
标量子查询
子查询返回单行单列
-- 查询年龄最大的学生信息
select * from student where age =
(select DISTINCT s.age from student s order by age desc LIMIT 1);
列(级)子查询
子查询返回一列多行
-- 查询选择了Java课程的学生信息
select * from student where sid in
(select sc.sid from score sc INNER JOIN course c on sc.cid=c.cid
where c.`name`='Java');
行(级)子查询
子查询返回一行多列,了解即可
-- 查询男生中年龄最大的学生信息
select *
from student
where (sex,age)=(select sex,age from student where sex='男' order by age desc limit 1)
-- 改用group by
select *
from student
where (sex,age)=(select sex,max(age) from student s group BY '男')
-- 正常写法
select *
from student
where sex='男' and age = (select max(age) from student s group BY '男')
表子查询(多行多列)
把查询出来的数据当做数据源使用
-- 查询Java和Python课程成绩
select c.`name`,score
from (select * from course where `name` in ('Java','Python')) c
INNER JOIN score on c.cid=score.cid
子查询插入数据
注:列数要一一对应,数据类型要一致或者兼容
-- 简单举例
INSERT into course(`NAME`) SELECT '计算机网络'
-- 等同于一般写法
INSERT into course(`NAME`) values('计算机网络')
子查询关键字
in / not in / some / any / all
=any或者=some 相当于in
>any表示只要大于子查询中的任意一个即可
>all表示大于子查询中的所有结果,相当于>max(子查询)
<any 和 <all同理
分表操作
建goods表,准备数据
drop table if exists goods;
create table goods(
id int UNSIGNED PRIMARY key auto_increment,
name varchar(20),
category varchar(10),
brand_name varchar(10),
price float(7,2)
);
insert into goods(name,category,brand_name,price)
values
('15.6英寸笔记本','商务本','华硕',3399),
('14英寸笔记本','上网本','联想',2799);
将商品类别独立成新表,创建表的同时用查询的出的数据直接插入新表
-- 字段名称必须一致(不同名时可以用起别名的方式指定列名),否则会创建新字段
drop table if EXISTS goods_brands;
create table goods_brands(
brand_id int UNSIGNED primary key auto_increment,
brand_name varchar(15)
)select DISTINCT brand_name from goods;
-- 用新表的生成的id直接更新商品表的类别
update goods g INNER JOIN goods_brands b
on g.brand_name = b.brand_name
set g.brand_name = b.brand_id;
-- 修改列名称和类型
alter table goods change brand_name brand_id INT;