目录
1.查询
1.1聚合查询
1.2 having 关键字
1.3 联表查询
1.3.1 内联和外联
1.3.2 自联合
1.3.3 子查询(subquery)/嵌套查询
聚合:
A班 | 小明 | 30 |
A班 | 小李 | 20 |
A班 | 小黄 | 30 |
B班 | 小王 | 40 |
B班 | 小红 | 20 |
A班 | 小苏 | 10 |
问:A班、B班各自有多少人
问:A班、B班分别的成绩总分是多少
问:A班、B班分别成绩最低的是多少
这些问题都需要对数据做聚合aggregation
1.聚合函数 count(*)、max(...)、min(...)、sum(...)、avg(...)
2.聚合字段(group by)
-- 查询学生一共有多少个
SELECT COUNT(*) FROM student;
-- 查询成绩一共有多少条
SELECT COUNT(*) FROM exam_result;
-- sum/avg/max/min 只能用于 数字类型的字段
-- 聚合的意思是竖着计算的
select sum(math) from exam_result;
-- 要计算某个人的语文 + 数学 + 英语,作为对比,这种不叫聚合
select chinese + math + english from exam_result where id = 1;
-- group : 分组进行聚合;
-- by 以哪个字段作为依据进行分组
-- 每种角色都是一个独立的聚合单位
select role, count(*) from emp group by role;
在进行聚合查询时,能出现在select 后面的,只能是:1)聚合函数 2)分组的字段
有些DBMS 没有遵循规范,比如 MySQL 是可以出现其他字段的,但最终结果中出现什么都是行为未定义。
在聚合后的数据中,再做一次数据过滤
having 在聚合之后 where 再聚合之前
两个表:
create table users (
uid int primary key auto_increment,
name varchar(45) not null
);
create table articles (
aid int primary key auto_increment,
author_id int not null,
title varchar(45) not null
);
联表查询:默认情况下的联表,结果是两张表的笛卡尔积
-- 在 from 后边直接跟 2 张表(2 张以上也可以)
-- 视为同时从 2 张表中查询数据
select * from users, articles; -- 一共 20 条数据 = 4 * 5
select * from users join articles;
这样查询没有什么用,所以一般联表查询都带着联表条件。
-- 添加 联表 条件后,得到的结果才是有意义的
select * from users, articles where users.uid = articles.author_id and users.name = '小红';
select * from users, articles where uid = author_id and users.name = '小红';
select * from users join articles on uid = author_id where users.name = '小红';
from 表1 jion 表2 on 联表条件 where 联表后的过滤条件——外联
from 表1 ,表2 where 联表条件 and 联表后的过滤条件——内联
内联:内联就是只保留交际部分
外联:左联(以左表为基准)(左外联)左表中的所有数据都要被体现出来
右联(右外联)
全外联:两部分都有(MySQL 不支持)
-- 左外联
select * from users left outer join articles on uid = author_id;
select * from users left join articles on uid = author_id;
-- 右外联
select * from users right outer join articles on uid = author_id;
select * from users right join articles on uid = author_id;
一张表和自己做联表查询
SELECT
st.id, st.name, s1.score 计算机成绩, s2.score Java成绩
FROM score s1 -- 计算机原理
JOIN score s2 -- Java
ON s1.student_id = s2.student_id
JOIN student2 st ON s1.student_id = st.id
WHERE
s1.course_id = 3 and s2.course_id = 1
and s1.score > s2.score;
查询结果基础上再查询
完全可以把一个 select 的结果,逻辑上视为一张表,继续 from 这张表去做查询
select *
from
(select * from exam_result where id > 4) as t
where id > 6;