MySQL 查询语句
Mysql查询语句时候一共分为以下几步,其中每一个操作都会产生一张虚拟的表,这个虚拟的表作为一个处理的输入,只是这些虚拟的表对用户来说是透明的,但是只有最后一个虚拟的表才会被作为结果返回。
语句执行顺序 :
顺序 |
名称 | 内容 |
---|---|---|
1 |
SELECT |
命令发起 |
2 |
* 或 AVG(字段)等 | 查询内容 |
3 |
FROM |
查询位置 |
4 |
WHERE |
条件查询 |
5 |
GROUP BY |
分组 |
6 |
HAVING |
筛选 |
7 |
ORDER BY (ASC/DESC) |
排序 |
8 |
LIMIT |
限制结果数 |
1、单表查询
- 查询指定的列
-- 在学生表中查询学号、姓名; select sno, sname from student ;
- 查询全部列
-- 查询学生表中全部信息 select * from student;
- 对查询后的列进行 起别别名
-- 查询全部学生的“姓名”及其“出生年”两列 select sname as 姓名,(2017-Sage) as 出生年 from student;
- 单条件查询
-- 查询职位是 salesman 的记录; select * from emp where job='Salesman'
- 多条件查询
-- 查询部门在10 或 20 的记录 select * from emp where deptno=10 or deptno=20; -- 查询部门在10的 或者部门在20且薪水小于2000的记录 select * from emp where deptno=10 or (deptno=20 and sal<=2000);
- 去重查询 ,使用 <distinct 列名> 语句
-- 查询选修了课程的学生学号 select distinct sno as 选修了课程的学生学号 from score;
- 查询空值(NULL)
-- 查询没有先修课的课程号和课程名。 select Cno as 课程号,Cname as 课程名,Cpno from course where Cpno is null; -- 查询所有有成绩的学生学号、课程号及成绩 select Sno as 学号,Cno as 课程号,Grade as 成绩 from SC where Grade is not null;
- 将NULL转化为实际值 ,使用 <coalesce(列名,替换值)>语句
-- 查询津贴为NULL ,替换为0 select coalesce(comm,0) from emp;
- 模糊查询 (LIKE % _ 语句) %表示任意字符;_表示单个字符
--查询员工姓名以a开头的记录 select * from emp where ename like 'a%'; --查询员工姓名中包含a的记录 select * from emp where ename like '%a%'; --查询员工姓名第二个字母以a开头的记录 select * from emp where ename like '_a%';
2、分组查询
GROUP BY 语句根据一个或多个列对结果集进行分组。
在分组的列上我们可以使用 COUNT, SUM, AVG,等函数。
-- 查询每个部门的薪水总和 select deptno,sum(sal) from emp group by deptno; -- 查询每个部门的津贴总和,空值不计算 select deptno,sum(comm) from emp group by deptno; -- 查询每个部门的津贴总和,空值替换为0 select deptno,sum(coalesce(comm,0)) from emp group by deptno; -- 查询每个部门的薪水在2000以上的总和 select deptno,sum(sal) from emp where sal>2000 group by deptno; -- 查询每个部门、每个职业的薪水总和 select deptno,job,sum(sal) from emp group by deptno,job;
3、排序查询
使用 MySQL 的 ORDER BY 子句来设定你想按哪个字段哪种方式来进行排序,再返回搜索结果。
使用 ASC 或 DESC 关键字来设置查询结果是按升序或降序排列。 默认情况下,它是按升序排列。
--将薪水从小到大升序排列; select * from emp order by sal; --将薪水从大到小降序排列; select * from emp order by sal desc; --查询薪水最高的前5名的记录; select * from emp order by sal desc limit 5; --查询每个部门 每个职务薪水总和的排名; select deptno,job,sum(sal) as new_sal from emp group by deptno,job order by deptno,new_sal;
4、逻辑查询
逻辑操作符:
- and \ or 且 或
- != (<>) 不等于
- is null 查询空值
- like 模糊查询
- between ……and (a>=b and a<c
逻辑表达式:
- case when ``` else ``` end语句
-- 查看每个员工的薪水,且将2000以下标为过低,4000以上标为过高,其余为可行 select ename,sal,case when sal<= 2000 then '过低' when sal>= 4000 then '过高' else '可行' end as status from emp; --查看每个员工编号、员工姓名,将薪水低于1000标为1,高于2000标为2 select empno,ename,case when sal >= 1000 and sal<2000 then 1 else 2 end as class from emp order by class;
5、HAVING查询
having字句可以让我们筛选成组后的各种数据,where字句在聚合前先筛选记录,也就是说作用在group by和having字句前。而 having子句在聚合后对组记录进行筛选。
--查询每个部门、职务、薪水总和,且只显示总和大于5000的 select deptno,job,sum(sal) from emp group by deptno,job having sum(sal)>5000; -- 同样的条件,如果用WHERE语句,只能写成如下 select deptno,job,new_sal from (select deptno,job,sum(sal) as new_sal from emp group by deptno,job) as a where new_sal>5000;
having和where的区别:
作用的对象不同。
WHERE 子句作用于表和视图,HAVING 子句作用于组。
WHERE 在分组和聚集计算之前选取输入行(因此,它控制哪些行进入聚集计算),
而 HAVING 在分组和聚集之后选取分组的行。
因此,WHERE 子句不能包含聚集函数; 因为试图用聚集函数判断那些行输入给聚集运算是没有意义的。
相反,HAVING 子句总是包含聚集函数。(严格说来,你可以写不使用聚集的 HAVING 子句, 但这样做只是白费劲。同样的条件可以更有效地用于 WHERE 阶段。)
这样比在 HAVING 里增加限制更加高效,因为我们避免了为那些未通过 WHERE 检查的行进行分组和聚集计算。
综上所述:having一般跟在group by之后,执行记录组选择的一部分来工作的,可以用聚合函数,如having sum(sal)>5000
where则是执行所有数据来工作的。