MySQL学习-子查询,分页查询,联合查询

MySQL学习-简单查询、条件查询、排序查询、分组查询

MySQL学习-SQL92连接查询,SQL99连接查询

子查询

    子查询:查询在其他语句中的SELECT语句,称为子查询或内查询
        外部的查询语句称为主查询或外查询
    外部的语句可以是INSERT,UPDATE,DELETE,SELECT等
    分类:
        按结果集的行列数:
                    标量子查询(单行子查询)(结果集只有一行一列)
                              一般搭配单行操作符:>,<,=,>=,<=,<>
                    列子查询(多行子查询)(结果集只有一列多行)
                              一般搭配多行操作符:in,any/some,all
                    行子查询(结果集有一行多列)
                    表子查询(结果集一般多行多列)
        按子查询出现的位置:
                    SELECT后面
                              只支持标量子查询
                    FROM后面
                              表子查询
                    WHERE或HAVING后面
                              标量子查询
                              列子查询
                              行子查询
                    EXISTS后面(相关子查询)结果只有1和0
                              表子查询

 子查询放在括号内
 子查询的执行优先于主查询的执行,因为主查询用到子查询的结果


一、WHERE或HAVING后面

#标量子查询(单行子查询)

#谁的工资比Abel高

SELECT * FROM employees WHERE salary>(
		SELECT salary FROM employees WHERE last_name='Abel');

#查询job_id与141号员工相同,salary比143号员工多的员工姓名,job_id和工资

SELECT last_name,job_id,salary FROM employees WHERE job_id=(
	SELECT job_id FROM employees WHERE employee_id=141) AND salary>(
			SELECT salary FROM employees WHERE employee_id=143);

#查询公司工资最少的员工的姓名,job_id,salary

SELECT last_name,job_id,salary FROM employees WHERE salary=(
		SELECT MIN(salary) FROM employees);

#查询最低工资大于50号部门最低工资的部门id及其最低工资

SELECT department_id,MIN(salary) FROM employees GROUP BY department_id
		HAVING MIN(salary)>(SELECT MIN(salary) FROM employees WHERE department_id=50) ;

#查询与姓名中包含字母u的员工相同部门的员工的员工号和姓名

SELECT employee_id,last_name FROM employees WHERE department_id IN(
		SELECT DISTINCT department_id FROM employees WHERE last_name LIKE '%u%') AND last_name NOT LIKE '%u%';

#查询管理者是K_ing的员工的姓名和工资

SELECT last_name,salary FROM employees WHERE manager_id IN(
		SELECT employee_id FROM employees WHERE last_name='K_ing');

SELECT e.last_name,e.salary FROM employees e INNER JOIN employees m ON
		e.manager_id=m.employee_id WHERE m.last_name='K_ing';

#列子查询(多行子查询)一列多行

#查询location_id是1400或1700的部门中所有的员工姓名

SELECT last_name FROM employees INNER JOIN departments
		ON employees.department_id=departments.department_id
				WHERE location_id IN (1400,1700);

SELECT last_name FROM employees WHERE department_id IN (
		SELECT DISTINCT department_id FROM departments WHERE location_id IN (1400,1700));

SELECT last_name FROM employees WHERE department_id =ANY (
		SELECT DISTINCT department_id FROM departments WHERE location_id IN (1400,1700));

#查询其它工种中员工工资比job_id为IT_PROG工种中任一工资低的员工的员工号、姓名、job_id以及salary

SELECT employee_id,last_name,job_id,salary FROM employees WHERE job_id<>'IT_PROG' AND
		salary<ANY(SELECT DISTINCT salary FROM employees WHERE job_id='IT_PROG');
#画区间图,小于最大值
SELECT employee_id,last_name,job_id,salary FROM employees WHERE job_id<>'IT_PROG' AND
		salary<(SELECT MAX(salary) FROM employees WHERE job_id='IT_PROG');

#查询其它工种中员工工资比job_id为IT_PROG工种的所有工资都低的员工的员工号、姓名、job_id以及salary

SELECT employee_id,last_name,job_id,salary FROM employees WHERE job_id<>'IT_PROG' AND
		salary<ALL(SELECT DISTINCT salary FROM employees WHERE job_id='IT_PROG');

SELECT employee_id,last_name,job_id,salary FROM employees WHERE job_id<>'IT_PROG' AND
		salary<(SELECT MIN(salary) FROM employees WHERE job_id='IT_PROG');

#行子查询

#查询员工编号最小并且工资最高的员工信息

SELECT * FROM employees WHERE (employee_id,salary)=(
	SELECT MIN(employee_id),MAX(salary) FROM employees);

#查询平均工资高于公司平均工资的部门有哪些

SELECT department_id FROM employees GROUP BY department_id HAVING AVG(salary)>(
		SELECT AVG(salary) FROM employees);

#查询公司中所有manager的详细信息

SELECT * FROM employees WHERE employee_id IN (
		SELECT DISTINCT manager_id FROM employees);

二、SELECT后面

#查询每个部门的员工个数(包含没人的部门)

SELECT d.department_id,(
		SELECT COUNT(*) FROM employees e WHERE e.department_id=d.department_id)
				FROM departments d ORDER BY d.department_id;

三、FROM后面

子查询结果作为一个表
#查询每个部门的平均工资的工资等级

SELECT tab.*,job_grades.grade_level FROM (
		SELECT department_id,AVG(salary) result FROM employees GROUP BY department_id) AS tab
				INNER JOIN job_grades ON tab.result BETWEEN lowest_sal AND highest_sal;

#查询各部门中工资比本部门平均工资高的员工的员工号、姓名、工资

SELECT employee_id,last_name,salary FROM employees AS e INNER JOIN (
		SELECT AVG(salary) AS av,department_id FROM employees GROUP BY department_id) AS tab
				ON tab.department_id=e.department_id WHERE e.salary>tab.av;

#查询平均工资最低的部门信息和该部门的平均工资

SELECT d.*,av FROM departments AS d INNER JOIN (
SELECT department_id,AVG(salary) AS av FROM employees
GROUP BY department_id ORDER BY AVG(salary) LIMIT 1) AS tab
ON tab.department_id=d.department_id;

四、EXISTS后面(相关子查询)布尔类型

#查询有员工的部门名

SELECT DISTINCT department_name FROM departments LEFT JOIN employees
		ON departments.department_id=employees.department_id
				WHERE employee_id IS NOT NULL;

SELECT department_name FROM departments WHERE EXISTS(
		SELECT * FROM employees WHERE employees.department_id=departments.department_id);

SELECT department_name FROM departments WHERE department_id IN(
		SELECT DISTINCT department_id FROM employees);

#查询各个部门的最高工资员工中工资最低者所属部门的最低工资

SELECT MIN(salary),department_id FROM employees GROUP BY department_id HAVING department_id IN(
SELECT department_id FROM employees GROUP BY department_id HAVING MIN(salary) IN(
SELECT MIN(max_sal) FROM (
SELECT MAX(salary) AS max_sal FROM employees GROUP BY department_id) AS tab))

总结
  WHERE型子查询:把内部查询的结果作为外层查询的比较条件。
  FROM型子查询:把内层的查询结果当成临时表,供外层再次查询。
  IN子查询:内层查询语句仅返回一个数据列,这个数据列的值将供外层查询语句进行比较。
  EXISTS子查询:把外层的查询结果,拿到内层,看内层是否成立。如果内层返回true,外层(也就是前面的语句)才会执行,否则不执行。
  ANY子查询:只要满足内层子查询中的任意一个比较条件,就返回一个结果作为外层查询条件。
  ALL子查询:内层子查询返回的结果需同时满足所有内层查询条件。

分页查询

    应用场景:当要显示的数据不可以一页显示完,需要分页提交SQL请求。
    语法:
                SELECT 查询列表------------7
                FROM 表1 别名----------------1
                [连接类型 JOIN 表2 别名]—2
                [ON 连接条件]------------------3
                [WHERE 筛选条件]-----------4
                [GROUP BY 分组]-------------5
                [HAVING 筛选条件]-----------6
                [ORDER BY 排序]-------------8
                LIMIT [OFFSET,] SIZE;------9

	OFFSET:要显示条目的起始索引(起始索引从0开始)
	SIZE:要显示的条目个数
	
	要显示的页数page,每页的条目数size
	LIMIT (page-1)*size,size

#显示前五条员工信息

SELECT * FROM employees LIMIT 0,5;
SELECT * FROM employees LIMIT 5;

#显示第11条~第25员工信息

SELECT * FROM employees LIMIT 10,15;

#有奖金的员工信息,并且工资较高的前10名显示出来

SELECT * FROM employees WHERE commission_pct IS NOT NULL ORDER BY salary DESC LIMIT 10;

#查询平均工资最低的部门信息

SELECT * FROM departments WHERE department_id=(
SELECT department_id FROM employees GROUP BY department_id HAVING AVG(salary)=(
SELECT MIN(av) FROM(
SELECT department_id,AVG(salary) AS av FROM employees GROUP BY department_id) AS tab));

#降序取第一条

SELECT * FROM departments WHERE department_id=(
SELECT department_id FROM employees GROUP BY department_id ORDER BY AVG(salary) LIMIT 1);

联合查询

    UNION:将多条查询语句的结果合并成一个结果
    语法:
            查询语句1
            UNION
            查询语句2
            UNION
             …
    应用场景:要查询的结果来自于多个表,且多个表没有直接的连接关系
    特点:
            1.要求多条查询语句的查询列数一致
            2.要求多条查询语句查询的每一列的类型和顺序最好一致
            2.UNION默认去重,如果不想去重使用 UNION ALL


#查询部门编号>90或邮箱包含a的员工信息

SELECT * FROM employees WHERE department_id>90 OR email LIKE '%a%';

SELECT * FROM employees WHERE department_id>90
UNION
SELECT * FROM employees WHERE email LIKE '%a%';

    

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值