不管函数处理多少条,只返回一条记录
如果你的数据可以分为多个组,那么返回的数据条数和组数相同
常用的多行函数有5个
max最大值
如果处理的值是字符串,将会把值按照字典序升序
min最小值
如果处理的值是字符串,将会把值按照字典序排序
avg平均值‘
只能用于数值型数据,求平均值
sum求和
如果求和的过程中有null,那么不会计算在内
count求总数
如果统计的数据中有null,不会吧null统计在内
经典的错误
--查询公司最低薪资的员工是谁?
select min(sal) , ename from emp;
MySQL语法不可行
Oracle语法不可行
将来工作的时候不能把普通列和组函数写在一起
虽然MySQL语法不会报错,但是给的结果是错误的
- -- 查询每种工作的平均薪资
- select job,avg(sal) from emp group by job;
- -- 查询每个部门的最高薪资和最低薪资
- select max(sal),min(sal) from emp;
- select deptno,max(sal),min(sal) from emp group by deptno;
- -- 查询每个部门的人数和每月工资总数
- select deptno,count(empno),sum(sal) from emp group by deptno;
-
- -- 查询每个部门,每种工作的平均薪资
- select deptno,job , avg(sal) from emp group by depyno,job;
- select deptno,job , avg(sal) from emp group by deptno,job order by dedptno,job;
-
- -- 查询个人姓名的平均薪资(尽量对多数据进行分组)
- select ename,max(sal),min(sal) from emp group by ename;
- -- 查询10,20部门中,并且在二月份入职员工中,每个部门中平均薪资高于1500的工作是什么,并按照部门,工作平均薪资进行排序
- select * from emp where deptno in (10,20);
- select deptno,job,avg(sal) from emp where deptno in (10,20) group by deptno,job having avg(sal)>1500;
- select deptno,job,avg(sal) from emp where deptno in (10,20) group by deptno,job having avg(sal)>1500 order by deptno,avg(sal);
- -- 美观写法
- SELECT
- deptno,
- job,
- avg(sal) '平均薪资'
- FROM
- emp
- WHERE
- deptno IN ( 10, 20 )
- GROUP BY
- deptno,
- job
- HAVING
- avg(sal) > 1500
- ORDER BY
- deptno,
- avg(sal);
select
我们要显示哪些列的数据
from
从哪张表中获取数据
where
从表中获取数据的时候进行行级的数据过滤
group by
对数据进行分组处理,一组获取对应的结果
having
组级过滤,组级过滤的数据必须是分组条件或者是组函数
order by
排序
asc desc
执行的顺序
from —>where —>group by—>having—>select—>order by
查询的两张表如果出现同名的列,我们需要将表名标注到列明前面
如果是非同名的列,表名可加可不加,推荐加上
表与表进行关联查询的时候,如果不添加关联条件,查询的总记录数就是a * b = 笛卡尔积
a 15 b 10 c 10 —> 1500条
多表查询的时候必须要加条件
- -- 查询每个员工所在的部门的名称
- select ename,deptno from emp;
- select deptno,dname from dept;
- select emp.ename,emp.deptno,dept.deptno,dept.dname from emp,dept;
- -- 等值关联查询
- select emp.eanme,emp.deptno,dept.deptno,depy.dname from emp,dept where emp.deptno = dept.deptno;
- selept emp.ename,dept.dname from emp,dept where emp.deptno = dept.deptno;
- -- 添加别名
- select e.ename,d.dname from emp e,dept d where e.deptno = d.deptno;
因为表的关联条件和业务查询条件放在了一起,为了防止混淆于是提供了下面三种方式
自然连接
会自动选择列名相同并且类型相同的列
- -- 查询薪资大于2000的员工姓名和部门名称
- select e.enamem,d.dname from emp e,dept d where e.deptno = d.deptno and e.sal>2000;
- -- 自然连接
- select e.ename,d.dname from emp e natural join dept d;
- select e.ename,d.dname from emp e natural join dept d where e.sal > 2000;
不需要MySQL帮我们选择等值连接的列,现在我们指定等值连接的列
- -- 查询薪资大于2000的员工姓名和部门名称 using
- select e.ename,d.dname from emp e join dept d using(deptno);
- select e.ename,d.dname from emp e join dept d using(deptno) where e.sal > 2000;
我们可以指定两张表关联的条件,可以非等值的操作
- -- 查询薪资大于2000的员工姓名和部门名称 using
- select e.ename,d.dname from emp e join dept d on(e.deptno = d.deptno)
- select e.ename,d.dname from emo e join depy d on(e.deptno = d.deptno) where e.sal>2000;
- -- 查询每个员工所对应的薪资等级
- select e.ename,s.grade from emp e,salgrade s where e.sal between s.losal and s.hisal;
- select e.ename,s.grade from emp e join salgrade s on(e.sal between s.losal and s.hisal);
- SELECT
- e.ename,
- d.dname,
- s.grade
- FROM
- emp e,
- depy d,
- salgrade s
- WHERE
- e.deptno = d.deptno
- AND e.sal BETWEEN s.losal AND s.hisal
- AND e.ename LIKE '%A%';
- ------------------------------------------------------------------------------------
- SELECT
- e.ename,
- d.dname,
- s.grade
- FROM
- emp e
- JOIN dept d USING ( deptno )
- JOIN salgrade s ON (e.sal BETWEEN s.losal AND s.hisal)
- WHERE
- e.ename LIKE '%A%';
当我们对两张表进行关联查询的时候,基于数据的基因导致其中一张表中的数据没办法被完全查询出来
外连接可以让没查询出来的数据也被显示出来
因为我们写SQL的时候表总有左右之分,外连接也分
左外连接:显示左面表所有的数据
右外连接:显示右面表所有的数据
- -- 查询每个部门的人数
- select deptno,count(empno) from emp group by deptno;
- select * from emp e join dept d using(deptno);
- select * from emp e left join dept d using(deptno);
- select * from emo e right join deot d using(deptno);
-
-
-
- select deptno,count(e.empno) from emp e right join dept d using(deptno) group by deptno;
-
- ----------------------全外连接
- SELECT
- deptno,
- e.ename,
- d.dname
- FROM
- emp e LEFT JOIN dept d USINg( deptno );
-
- ---------------------Oracle的全外连接使用Full Join
我们要查询的两个字段同时处于一张表上,我们只能将一张表当作含有不同意义的两张表去处理
给相同的表取不同的简称(按照所代表的含义去取)
- -- 查询每个员工与其直属领导的名字
- select e.ename,m.ename from emp e,emp m where e.mgr = m.empno;
- select e.ename,m.ename from emp e join emp m on(e.mgr = m.ename);
把一个SQL语句的查询结果当成另外一个SQL语句的查询结果
- -- 查询公司中薪资最低的员工姓名
- select ename,sal from emp where sal = (select min(sal) from emp);
- -- 查询公司中谁的薪资高于平均薪资
- select ename,sal from emp where sal > (select avg(sal) from emp);
-
- -- 谁的薪资高于20部门员工的薪资
- select ename,sal from emp where sal > all(select sal from emp where deptno = 20);
- select ename,sal from emp where sal > some(select sal from emp where deptno = 20);
- select ename,sal from emp where sal > some(select sal from emp where deptno = 20);
如果我们所需要的查询条件需要别的SQL语句来提供
如果只需要一个条件那么可以使用子查询来完成
如果需要多个查询条件,这时就要将所有的查询结果当做伪表进行管理
我们需要把一些含有特殊符号的列名设置别名,然后给伪表设置一个别名(见名知意)
- -- 查询高于自己部门平均薪资的员工信息
- select deptno,avg(sal) avgsal from emp group by deptno;
-
- SELECT
- e.ename,
- e.sal,
- e.deptno
- FROM
- emp e,
- ( SELECT deptno, avg(sal) avgsal FROM emp GROUP BY deptno ) d
- SELECT
- e.deptno = d.deptno
- AND e.sal > d.avgsal;