mysql数据库(3)--内,外连接查询、子查询、合并、分页【入门】

可以参照前两个帖子,按顺序的,mysql数据库(1)有完整的建表语句

mysql数据库(1)---简单查询

mysql数据库(2)---单行函数、多行函数、分组查询

-- 简单查询语句的完整语法

/*完整语法

SELECT 查询列表

FROM 表名

WHERE 查询条件

CROUP BY 分组字段

HAVING 查询条件

ORDER BY 排序字段

-- 以上语句的执行顺序

-- 1,SELECT FROM 查询出全部的数据

-- 2,使用WHERE对查询结果进行过滤

-- 3,过滤后的数据使用GROUP BY进行分组

-- 4,分组后的数据使用HAVING再次过滤

-- 5,再次过滤后的数据用ORDER BY排序

-- 注意事项:

-- 1,以上语句的顺序是固定的,不能改变

-- 2,对数据过滤得时候,优先使用WHERE进行过滤,这样的效率比较高

*/

-- 把津贴为NULL的员工按照部门编号分组查询平均工资,并且显示平均工资大于XXX的数据,然后按照平均工资排序

SELECT dadtno,ROUND(AVG(sal)) "平均工资"

FROM emp

WHERE comm IS NOT NULL

GROUP BY dadtno

HAVING 平均工资>1000

ORDER BY 平均工资;

-- 【【1】】,连接查询,也称为多表查询、跨表查询;也就是从多个表中查询相关的数据

-- 注意:多表查询的时候,使用的表越多,查询的速度越慢

-- 多表查询的分类:

-- 1,按照连接的方式区分

-- (1)内连接:可以查询满足一一对应关系的数据;例如这个员工有所属的部门,这个部门有所属的员工,

-- 这样的数据满足一一对应的关系可以使用内连接查询出来

-- (2)外连接:可以查询不满足一一对应关系的数据;例如这个员工没有所属的部门,这个部门没有所属的员工,

-- 这样的数据不满足一一对应的关系,使用内连接查询出来是无法查询的出来,但是可以使用外连接进行查询

-- 2,按照语法的年代划分

-- (1)SQL1992标准:FROM后面是多个表,多个表之间通过逗号分隔

-- (2)SQL1999标准:FROM后面是一个表,通过jOIN方式连接其他表

-- 【1.1】,内连接:可以查询满足一一对应关系的数据;例如这个员工有所属的部门,这个部门有所属的员工,

-- 这样的数据满足一一对应的关系可以使用内连接查询出来

-- 内连接的分类:

-- (1)等值连接

-- (2)非等值连接

-- (3)自连接

-- 【1.1.1】,内连接之等值连接:建立在父子表关系上,用等号来连接两个表

-- (1)sql1992语法

-- 1,查询工资信息及其部门信息

SELECT e.ename,e.empNo,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.dadtno,d.dname,d.loc

FROM emp e,dept d

WHERE e.dadtno = d.dadtno;

-- 2,在等值连接的基础上,可以使用AND加入其他的查询条件

SELECT e.ename,e.empNo,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.dadtno,d.dname,d.loc

FROM emp e,dept d

WHERE (e.dadtno = d.dadtno) AND (d.dadtno=20);

-- 3,查询工资在1600-3000之间的员工信息及其部门信息

-- 1,等值查询 2,使用AND加入其他的查询条件,过滤1660-3000的数据

SELECT e.ename,e.empNo,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.dadtno,d.dname,d.loc

FROM emp e,dept d

WHERE (e.dadtno = d.dadtno) AND (e.sal BETWEEN 1600 AND 3000);

-- (2)sql1999语法

-- 使用内连接时,INNER可以忽略

SELECT e.ename,e.empNo,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.dadtno,d.dname,d.loc

FROM emp e

INNER JOIN dept d ON (e.dadtno = d.dadtno);

-- 2,在等值连接的基础上,可以使用AND加入其他的查询条件

SELECT e.ename,e.empNo,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.dadtno,d.dname,d.loc

FROM emp e

INNER JOIN dept d ON (e.dadtno = d.dadtno) AND (d.dadtno=20);

-- 3,查询工资在1600-3000之间的员工信息及其部门信息

SELECT e.ename,e.empNo,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.dadtno,d.dname,d.loc

FROM emp e

INNER JOIN dept d ON (e.dadtno = d.dadtno)

WHERE (e.sal BETWEEN 1600 AND 3000);

-- 表salgrade

CREATE TABLE salgrade(

grade INT(10),

losal INT(10),

hisal INT(10)

)

-- 【1.1.2】,内连接之非等值连接,两个表之间没有父子关系,用非等号来连接

-- SQL1992语法

SELECT e.empNo,e.ename,e.sal,s.grade,s.losal,s.hisal

FROM emp e , salgrade s

WHERE (e.sal BETWEEN s.losal AND s.hisal);

-- 使用AND加入其他的查询条件

SELECT e.empNo,e.ename,e.sal,s.grade,s.losal,s.hisal

FROM emp e , salgrade s

WHERE (e.sal BETWEEN s.losal AND s.hisal) AND (s.grade=1);

-- sql1999语法

SELECT e.empNo,e.ename,e.sal,s.grade,s.losal,s.hisal

FROM emp e

JOIN salgrade s ON (e.sal BETWEEN s.losal AND s.hisal);

-- 使用AND加入其他的查询条件

SELECT e.empNo,e.ename,e.sal,s.grade,s.losal,s.hisal

FROM emp e

JOIN salgrade s ON (e.sal BETWEEN s.losal AND s.hisal) AND (s.grade=1);

-- 使用WHERE加入其他的查询条件

SELECT e.empNo,e.ename,e.sal,s.grade,s.losal,s.hisal

FROM emp e

JOIN salgrade s ON (e.sal BETWEEN s.losal AND s.hisal) WHERE (s.grade=1);

-- 【1.1.3】,内连接之自连接:使用别名将一个表虚拟成为两个表(父子表)然后在这两个表上面做等值连接

-- 查询员工的信息及其直接领导的信息

-- SQL1992语法

SELECT e.empNo "员工编号",e.ename "员工名字",m.empNo "经理编号",m.ename "经理名字"

FROM emp e,emp m

WHERE (e.mgr = m.empNo) AND (m.empNo=1239);

-- SQL1999语法

SELECT e.empNo "员工编号",e.ename "员工名字",m.empNo "经理编号",m.ename "经理名字"

FROM emp e

JOIN emp m ON (e.mgr = m.empNo) WHERE (m.empNo=1239);

-- 【1.2】,外连接:可以查询不满足一一对应关系的数据;例如这个员工没有所属的部门,这个部门没有所属的员工,

-- 这样的数据不满足一一对应的关系,使用内连接查询出来是无法查询的出来,但是可以使用外连接进行查询

-- 使用外连接查询数据的条数大于等于内连接查询数据的条数

-- 数据库把不匹配的数据设置为NULL;

-- 外连接的分类(可以把OUTER给忽略不写)

-- (1)左外连接(LEFT OUTER JOIN)

-- (2)右外连接(RIGHT OUTER JOIN)

-- (3)全外连接(FULL OUTER JOIN)

-- 【1.2.1】,左外连接(LEFT OUTER JOIN):用LEFT OUTER JOIN作为分界线emp表就是左表,左外连接可以把左表中

-- 不满足的对应关系的数据查询出来;

-- 例如1243这个员工没有对应的部门,可以查询出来

SELECT e.empNo,e.ename,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.dadtno,d.dname,d.loc

FROM emp e

LEFT JOIN dept d ON (e.dadtno = d.dadtno);

-- 【1.2.2】,右外连接(RIGHT OUTER JOIN)用RIGHT OUTER JOIN作为分界线,dept表示在右表;右连接可以把右表不满足的数据查询出来

-- 例如:40这个部门没有对应的员工,可以被查出来

SELECT e.empNo,e.ename,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.dadtno,d.dname,d.loc

FROM emp e

RIGHT JOIN dept d ON (e.dadtno = d.dadtno);

--【1.2 3】,左外连接的功能可以用右外连接的功能(左右表也可以互换)

-- 【1.2.4】,全外连接(FULL OUTER JOIN)用FULL OUTER JOIN作为分界线,把两个表中不满足对应关系的数据都查询出来;

-- 在oracle支持;在mysql不支持,会报错

SELECT e.empNo,e.ename,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.dadtno,d.dname,d.loc

FROM emp e

FULL JOIN dept d ON (e.dadtno = d.dadtno);

-- 查询员工及其领导的信息;并显示没有领导的员工

SELECT e.empNo "员工编号",e.ename "员工姓名",m.empNo "经理编号",m.ename "经理名字"

FROM emp e

LEFT JOIN emp m ON (e.mgr = m.empNo);

-- 【【2】】,多表查询

-- 从N个表中查询相关的数据,需要N-1个INNER JOIN子句即可

-- 查询员工信息,部门信息及其员工工资级别信息,并是1000-3000的范围

-- SQL1992语法

SELECT e.empNo,e.ename,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.dadtno,d.dname,d.loc,s.grade,s.losal,s.hisal

FROM emp e,dept d,salgrade s

WHERE (e.dadtno = d.dadtno) AND (e.sal BETWEEN s.losal AND s.hisal) AND (e.sal BETWEEN 1000 AND 3000);

-- SQL1999语法

SELECT e.empNo,e.ename,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.dadtno,d.dname,d.loc,s.grade,s.losal,s.hisal

FROM emp e

JOIN dept d ON (e.dadtno=d.dadtno)

JOIN salgrade s ON (e.sal BETWEEN s.losal AND s.hisal)

WHERE (e.sal BETWEEN 1000 AND 3000);

-- 【【3】】,子查询:用来给主查询提供查询条件而首先执行的一个查询;主查询使用子查询的结果;子查询必须要放在()里面

-- 子查询的分类

-- 1,出现在WHERE中的子查询;用来给查询提供查询条件的

-- 2,出现下在FROM后面的子查询,用来给主查询提供查询数据的,也就是先执行子查询,然后把子查询的查询结果当做一个虚表

-- 然后主查询从这个虚表中查询数据

-- 3,出现在查询列表的子查询,功能类似于连接效果,这种方式了解即可

-- 【3.1】,出现在WHERE中的子查询;用来给查询提供查询条件的

-- 查询工资比平均工资低的员工

SELECT *

FROM emp

WHERE sal < (SELECT AVG(sal) FROM emp);

--【3.2】,出现下在FROM后面的子查询,用来给主查询提供查询数据的,也就是先执行子查询,然后把子查询的查询结果当做一个虚表

-- 然后主查询从这个虚表中查询数据

SELECT T.*

FROM (SELECT e.empNo,e.ename,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.dadtno,d.dname,d.loc,s.grade,s.losal,s.hisal

FROM emp e

JOIN dept d ON (e.dadtno = d.dadtno)

JOIN salgrade s ON (e.sal BETWEEN s.losal AND s.hisal)) T

WHERE T.empNo = 1234;

-- 【3.3】,出现在查询列表的子查询,功能类似于连接效果,这种方式了解即可

SELECT e.*,(SELECT d.dname FROM dept d WHERE e.dadtno = d.dadtno) daname

FROM emp e;

-- 【【4】】,分组查询,多表查询,子查询综合应用

-- 1,取得每个部门最高薪水的员工名称

-- 思路:按照部门编号分组查询最高工资当做一个临时表,和emp e表进行连接;连接条件(e.dadtno=T.dadtno AND e.sal = T.MAXsal)

SELECT T.dadtno,T.MAXsal,e.ename

FROM emp e

JOIN (

SELECT dadtno, MAX(sal) MAXsal

FROM emp

GROUP BY dadtno ) T ON (e.dadtno = T.dadtno AND e.sal = T.MAXsal)

ORDER BY T.dadtno;

-- 【【5】】,使用UNION把两个表查询结果合并成为一个查询结果

-- 注意:合并两个查询结果的时候,要求两个查询结果必须一致(查询字段的类型、个数、顺序必须一致)

-- UNION有两种使用方式

-- 1,UNION:会合并相同的数据

-- 2,UNION ALL:不会合并相同的数据

-- 【5.1】,UNION:会合并相同的数据

SELECT e.empNo,e.ename,e.job,e.mgr,e.hiredate,e.sal,e.comm,e.dadtno

FROM emp e

WHERE e.sal>1000

UNION

SELECT e.empNo,e.ename,e.job,e.mgr,e.hiredate,e.sal,e.comm,e.dadtno

FROM emp e

WHERE e.sal>3000;

-- 【5.2】,UNION ALL:不会合并相同的数据

SELECT e.empNo,e.ename,e.job,e.mgr,e.hiredate,e.sal,e.comm,e.dadtno

FROM emp e

WHERE e.sal>1000

UNION ALL

SELECT e.empNo,e.ename,e.job,e.mgr,e.hiredate,e.sal,e.comm,e.dadtno

FROM emp e

WHERE e.sal>3000;

-- 【5.3】,使用UNION把一个左外连接的结果和右外连接的结果合并起来实现全外连接的效果

SELECT e.empNo,e.ename,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.dadtno,d.dname,d.loc

FROM emp e

LEFT JOIN dept d ON (e.dadtno = d.dadtno)

UNION

SELECT e.empNo,e.ename,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.dadtno,d.dname,d.loc

FROM emp e

RIGHT JOIN dept d ON (e.dadtno = d.dadtno);

-- 【【6】】,LIMIT的使用,可以查询表中最高前面的几条数据或中间某几条数据

-- LIMIT的用法:LIMIN a,b;a是开始得索引(索引默认0开始);b是连接条数

-- 注意:LIMIT只能在mysql和SQLserver中有效

-- 使用LIMIN查询最高工资前面4个一个信息

SELECT *

FROM emp

GROUP BY sal DESC LIMIT 0,4;

猜你喜欢

转载自blog.csdn.net/wssc63262/article/details/85012728