MySQL之多表查询

本文详细介绍了SQL查询的基础知识,包括合并结果集、连接查询、子查询等,并通过实例演示了如何利用这些技术解决实际问题,如筛选特定部门员工、查询特定条件下的员工信息等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

语句关键字顺序:

select *

from emp, dept, (select * from emp)

where

group by

having

order by

limit

  ①. 分类:

    * 合并结果集(了解)

    * 连接查询

    * 子查询

 

②:

1)合并结果集

  * 要求被合并的表中,列的类型和列数相同(结果集相同)

  * UNION,去除重复行

  * UNION ALL,不去除重复行

 

SELECT * FROM cd

UNION ALL

SELECT * FROM ab;

 

2)连接查询

  ①. 分类

    * 内连接:返回连接表中符合连接条件和查询条件的数据行。

    * 外连接:不但返回符合连接和查询条件的数据行,还返回不符合条件的一些行。

      > 左外连接:左表记录无论是否满足条件都会查询出来,而右表只有满足条件才能出来。左表中不满足条件的记录,右表部分都为NULL

      > 右外连接:右表记录无论是否满足条件都会查询出来,而左表只有满足条件才能出来。右表不满足条件的记录,其左表部分都为NULL

      > 全外连接(MySQL不支持,可以使用UNION关键字来实现):将左外连接的结果集与右外连接的结果集合并在一起

    * 自然连接(属于一种简化方式):省略了ON关键字后的条件

 

  ②. 内连接

    * 方言:SELECT * FROM 表1 别名1, 表2 别名2 WHERE 别名1.xx=别名2.xx

     (形成的中间表为经过WHERE条件过滤的笛卡尔积)

    * 标准:SELECT * FROM 表1 别名1 INNER JOIN 表2 别名2 ON 别名1.xx=别名2.xx

    (形成的中间表为经过ON条件过滤后的笛卡尔积)

    * 自然:SELECT * FROM 表1 别名1 NATURAL JOIN 表2 别名2

   (相对于标准的少了ON,因为它会自动寻找两个表之间的名称相同的列,进行自动匹配)

    * 内连接查询出的所有记录都满足条件。

 

  ③. 外连接

    * 左外:SELECT * FROM 表1 别名1 LEFT OUTER JOIN 表2 别名2 ON 别名1.xx=别名2.xx

      > 左表记录无论是否满足条件都会查询出来,而右表只有满足条件才能出来。左表中不满足条件的记录,右表部分都为NULL

    * 左外自然:SELECT * FROM 表1 别名1 NATURAL LEFT OUTER JOIN 表2 别名2

    * 右外:SELECT * FROM 表1 别名1 RIGHT OUTER JOIN 表2 别名2 ON 别名1.xx=别名2.xx

      > 右表记录无论是否满足条件都会查询出来,而左表只有满足条件才能出来。右表不满足条件的记录,其左表部分都为NULL

    * 右外自然:SELECT * FROM 表1 别名1 NATURAL RIGHT OUTER JOIN 表2 别名2

    * 全连接:可以使用UNION来完成全连接

 

3)子查询

:查询中有查询(查看select关键字的个数!)

  ①. 出现的位置:

    * where后作为条件存在

    * from后作为表存在(多行多列)

 

  ②. 条件

    * (***)单行单列:SELECT * FROM 表1 别名1 WHERE 列1 [=、>、<、>=、<=、!=] (SELECT 列 FROM 表2 别名2 WHERE 条件)

    * (**)多行单列:SELECT * FROM 表1 别名1 WHERE 列1 [>、<] [IN, ALL, ANY] (SELECT 列 FROM 表2 别名2 WHERE 条件)

    * (*)单行多列:SELECT * FROM 表1 别名1 WHERE (列1,列2) IN (SELECT 列1, 列2 FROM 表2 别名2 WHERE 条件)

    * (***)多行多列:SELECT * FROM 表1 别名1 , (SELECT ....) 别名2 WHERE 条件

 

====================================================

 

笛卡尔积

{a, b, c} {1,2}

{a1, a2, b1, b2, c1, c2}

 

 

====================================================

 

1. 查出至少有一个员工的部门。显示部门编号、部门名称、部门位置、部门人数。

3. 列出所有员工的姓名及其直接上级的姓名。

4. 列出受雇日期早于直接上级的所有员工的编号、姓名、部门名称。

5. 列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门。

7. 列出最低薪金大于15000的各种工作及从事此工作的员工人数。

8. 列出在销售部工作的员工的姓名,假定不知道销售部的部门编号。

9. 列出薪金高于公司平均薪金的所有员工信息,所在部门名称,上级领导,工资等级。

10.列出与庞统从事相同工作的所有员工及部门名称。

11.列出薪金高于在部门30工作的所有员工的薪金的员工姓名和薪金、部门名称。

 

练习答案:

/*

1. 查出至少有一个员工的部门。显示部门编号、部门名称、部门位置、部门人数。

*/

SELECT dept.*,z1.cnt

FROM dept,(SELECT deptno,COUNT(*) cnt FROM emp GROUP BY deptno) z1

WHERE dept.deptno=z1.deptno

 

 

/*

3. 列出所有员工的姓名及其直接上级的姓名。

*/

SELECT e.ename,m.ename 领导  

FROM emp e,emp m

WHERE e.mgr=m.empno

 

SELECT e.ename,IFNULL(m.ename,'BOSS') 领导

FROM emp e LEFT OUTER JOIN emp m

ON e.mgr=m.empno

/*

4. 列出受雇日期早于直接上级的所有员工的编号、姓名、部门名称。

*/

SELECT e.empno,e.ename,dept.dname

FROM emp e,emp m,dept

WHERE e.mgr=m.empno AND e.hiredate < m.hiredate  AND e.deptno=dept.deptno

 

/*

5. 列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门。

*/

SELECT dept.dname,emp.*

FROM dept LEFT OUTER JOIN emp

ON dept.deptno=emp.deptno

 

/*

7. 列出最低薪金大于15000的各种工作及从事此工作的员工人数。

*/

SELECT job,COUNT(*) FROM emp GROUP BY job HAVING MIN(sal)>15000

 

/*

8. 列出在销售部工作的员工的姓名,假定不知道销售部的部门编号。

*/

SELECT ename FROM emp WHERE emp.deptno=(SELECT deptno FROM dept WHERE dname='销售部')

 

/*

9. 列出薪金高于公司平均薪金的所有员工信息,所在部门名称,上级领导,工资等级。

*/

SELECT e.*,d.dname,m.ename,s.grade

FROM emp e,dept d,emp m,salgrade s

WHERE e.sal>(SELECT AVG(sal) FROM emp) AND e.deptno=d.deptno AND e.mgr=m.empno AND e.sal BETWEEN s.losal AND s.hisal

 

SELECT e.*,d.dname,m.ename,s.grade

FROM

       emp e LEFT OUTER JOIN dept d ON e.deptno=d.deptno

                            LEFT OUTER JOIN emp m ON e.mgr=m.empno

                            LEFT OUTER JOIN salgrade s ON e.sal BETWEEN s.losal AND s.hisal

WHERE e.sal>(SELECT AVG(sal) FROM emp)

 

/*

10.列出与庞统从事相同工作的所有员工及部门名称。

*/

SELECT e.*,d.dname

FROM emp e,dept d

WHERE e.deptno=d.deptno AND job=(SELECT job FROM emp WHERE ename='庞统')

 

/*

11.列出薪金高于在部门30工作的所有员工的薪金的员工姓名和薪金、部门名称。

*/

SELECT e.ename,e.sal,d.dname

FROM emp e,dept d

WHERE e.deptno=d.deptno AND sal>ALL (SELECT sal FROM emp WHERE deptno=30)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值