MySQL练习(一):SELECT使用篇

文章目录

  • 1. 基本select语句
  • 2. 运算符练习
  • 3. 排序与分页
  • 4. 多表查询
  • 5. 单行函数
  • 6. 聚合函数
  • 7. 子查询

1. 基本select语句

  1. 别名AS可加可不加,但是有空格的别名的双引号要加!
  2. IFNULL(a,b):如果a中有空值,就变成b!
  3. where要写在from后面!
  4. DESCRIBE函数显示表的全部结构!
#第03章_基本的SELECT语句的课后练习

# 1.查询员工12个月的工资总和,并起别名为ANNUAL SALARY
#理解1:计算12月的基本工资
SELECT employee_id,last_name,salary*12 AS "ANNUAL SALARY"
FROM employees;
#注意:别名AS可加可不加,但是别名的双引号要加!

#理解2:计算12月的基本工资和奖金
SELECT employee_id,last_name,salary*(1+IFNULL(commission_pct,0))*12 AS "ANNUAL SALARY"
FROM employees;
#注意:IFNULL(a,b):如果a中有空值,就变成b!

# 2.查询employees表中去除重复的job_id以后的数据
SELECT DISTINCT job_id
FROM employees;

# 3.查询工资大于12000的员工姓名和工资
SELECT employee_id,last_name
FROM employees
WHERE salary>12000
#注意:where要写在from后面!

# 4.查询员工号为176的员工的姓名和部门号
SELECT last_name,department_id
FROM employees
WHERE employee_id = 176;

# 5.显示表 departments 的结构,并查询其中的全部数据 
DESCRIBE departments;

SELECT * FROM departments;
#注意:DESCRIBE函数显示表的全部结构!


2. 运算符练习

  1. 安全等于运算符(<=>)与等于运算符(=)的作用是相似的,唯一的区别是‘<=>’可以用来对NULL进行判断。或者使用 IS NULL
  2. 没有 !<=> NULL 的写法,只有IS NOT NULL,或WHER…NOT NULL
# 第04章_运算符课后练习

# 1.选择工资不在5000到12000的员工的姓名和工资
SELECT last_name,salary
FROM employees
WHERE salary>12000 OR salary<5000;

# 2.选择在20或50号部门工作的员工姓名和部门号
SELECT last_name,department_id
FROM employees
WHERE department_id=20 OR department_id=50;

# 3.选择公司中没有管理者的员工姓名及job_id
SELECT last_name,job_id,manager_id
FROM employees
WHERE manager_id IS NULL;

SELECT last_name,job_id,manager_id
FROM employees
WHERE manager_id <=> NULL;
#注意:不能写manager_id = NULL!!安全等于运算符(<=>)与等于运算符(=)的作用是相似的,
#唯一的区别是‘<=>’可以用来对NULL进行判断。


# 4.选择公司中有奖金的员工姓名,工资和奖金级别
SELECT last_name,salary,commission_pct
FROM employees
WHERE commission_pct IS NOT NULL;


SELECT last_name,salary,commission_pct
FROM employees
WHERE NOT commission_pct <=> NULL;
#注意:不能写 !<=> NULL!!


# 5.选择员工姓名的第三个字母是a的员工姓名
SELECT last_name
FROM employees
WHERE last_name LIKE '__a%';
#注意:为什么..不行???


# 6.选择姓名中有字母a和k的员工姓名
SELECT last_name
FROM employees
WHERE last_name LIKE '%a%k%' OR last_name LIKE '%k%a%';
#注意:不光%a%k%有可能!!!%k%a%也很有可能!!


# 7.显示出表 employees 表中 first_name 以 'e'结尾的员工信息
SELECT last_name
FROM employees
WHERE last_name LIKE 'e$';
#注意:还有一种写法是'%e'


# 8.显示出表 employees 部门编号在 80-100 之间的姓名、工种
SELECT last_name,job_id
FROM employees
WHERE department_id BETWEEN 80 AND 100;
#方式2:推荐,与方式1相同
#where department_id >= 80 and department_id <= 100;
#方式3:仅适用于本题的方式。
#where department_id in (80,90,100);

# 9.显示出表 employees 的 manager_id 是 100,101,110 的员工姓名、工资、管理者id
SELECT last_name,salary,manager_id
FROM employees
WHERE manager_id IN (100,101,110);

3. 排序与分页

  1. 建议别名都写上双引号
  2. LIMIT的写法没括号
  3. 方括号“[]”指定一个字符集合,只匹配其中任何一个字符,即为所查找的文本。
#第05章_排序与分页的课后练习


#1. 查询员工的姓名和部门号和年薪,按年薪降序,按姓名升序显示 
SELECT last_name,department_id,salary*12 annual_salary
FROM employees
ORDER BY annual_salary DESC, last_name ASC;
# 升序:ASC (ascend)
# 降序:DESC (descend)
#重命名的列不一样要双引号,建议都写


#2. 选择工资不在 8000 到 17000 的员工的姓名和工资,按工资降序,显示第21到40位置的数据 
SELECT last_name,salary
FROM employees
ORDER BY salary DESC
LIMIT 20,20;
#limit的写法没有括号


#3. 查询邮箱中包含 e 的员工信息,并先按邮箱的字节数降序,再按部门号升序
SELECT employee_id,last_name,email,department_id
FROM employees
WHERE email REGEXP 'e'
ORDER BY LENGTH(email) DESC, department_id ASC;
#单双引号什么区别??
#方括号“[]”指定一个字符集合,只匹配其中任何一个字符,即为所查找的文本。

4. 多表查询

  1. 连接必须写含有等于的ON式
  2. 连接语句中间不能写逗号

# 第06章_多表查询的课后练习

# 1.显示所有员工的姓名,部门号和部门名称。
SELECT e.last_name,e.department_id,d.department_name
FROM employees e LEFT OUTER JOIN departments d
ON e.`department_id` = d.`department_id`
#这里直接内连接是不对的!因为要显示所有员工,但不是所有员工都有部门号和名称
#需要使用左外连接
#注意不是使用WHERE而是使用ON


# 2.查询90号部门员工的job_id和90号部门的location_id
SELECT e.`job_id`,d.`location_id`
FROM employees AS e INNER JOIN departments AS d
ON e.`department_id` = d.`department_id`
WHERE d.`department_id` = 90;

#连接必须写含有等于的ON式
#WHERE当中要写哪一个的那个属性等于什么


DESC employees;
DESC departments;
DESC locations;

# 3.选择所有有奖金的员工的 last_name , department_name , location_id , city
SELECT e.`last_name`, d.`department_name`,d.`location_id`,l.`city`
FROM employees AS e LEFT JOIN departments AS d 
ON e.`department_id` = d.`department_id`
LEFT JOIN locations AS l ON d.`location_id` = l.`location_id`
WHERE e.`commission_pct` IS NOT NULL;
#注意:连接语句中间不能写逗号!

SELECT e.last_name ,e.`commission_pct`, d.department_name , d.location_id , l.city
FROM employees e LEFT JOIN departments d
ON e.`department_id` = d.`department_id`
LEFT JOIN locations l
ON d.`location_id` = l.`location_id`
WHERE e.`commission_pct` IS NOT NULL; #也应该是35条记录



# 4.选择city在Toronto工作的员工的 last_name , job_id , department_id , department_name 
SELECT e.`last_name`, e.`job_id`, d.`department_id`,d.`department_name`
FROM employees e JOIN departments d 
ON e.`department_id` = d.`department_id`
JOIN locations l 
ON d.`location_id` = l.`location_id`
WHERE l.`city` = 'Toronto';


SELECT e.last_name , e.job_id , e.department_id , d.department_name
FROM employees e JOIN departments d
ON e.`department_id` = d.`department_id`
JOIN locations l
ON d.`location_id` = l.`location_id`
WHERE l.`city` = 'Toronto';


#sql92语法:



# 5.查询员工所在的部门名称、部门地址、姓名、工作、工资,其中员工所在部门的部门名称为’Executive’
SELECT d.department_name,l.street_address,e.last_name,e.job_id,e.salary
FROM departments d LEFT JOIN employees e
ON e.`department_id` = d.`department_id`
LEFT JOIN locations l
ON d.`location_id` = l.`location_id`
WHERE d.`department_name` = 'Executive';

SELECT d.department_name,l.street_address,e.last_name,e.job_id,e.salary
FROM employees e LEFT JOIN departments d
ON e.`department_id` = d.`department_id`
LEFT JOIN locations l
ON d.`location_id` = l.`location_id`
WHERE d.`department_name` = 'Executive';


# 6.选择指定员工的姓名,员工号,以及他的管理者的姓名和员工号,结果类似于下面的格式
employees	Emp#	manager	Mgr#
kochhar		101	king	100
SELECT emp.last_name "employees",emp.employee_id "Emp#",mgr.last_name "manager", mgr.employee_id "Mgr#"
FROM employees emp LEFT JOIN employees mgr
ON emp.manager_id = mgr.employee_id
#注意:因为有些人没有领导!所以需要左外连接

SELECT emp.last_name "employees",emp.employee_id "Emp#",mgr.last_name "manager", mgr.employee_id "Mgr#"
FROM employees emp LEFT JOIN employees mgr
ON emp.manager_id = mgr.employee_id;


# 7.查询哪些部门没有员工
SELECT d.department_id
FROM departments d LEFT JOIN employees e
ON d.`department_id` = e.`department_id`
WHERE e.`department_id` IS NULL;



#本题也可以使用子查询:暂时不讲

# 8. 查询哪个城市没有部门 
SELECT l.location_id,l.city
FROM locations l LEFT JOIN departments d
ON l.`location_id` = d.`location_id`
WHERE d.`location_id` IS NULL;



# 9. 查询部门名为 Sales 或 IT 的员工信息
SELECT d.`department_id`,d.`department_name`,e.`job_id`,e.`last_name`
FROM departments d LEFT JOIN employees e
ON d.`department_id` = e.`department_id`
WHERE d.`department_name`='Sales' OR d.`department_name`='IT';
#WHERE d.`department_name` IN ('Sales','IT');

5. 单行函数

# 1.显示系统时间(注:日期+时间)
SELECT NOW(), SYSDATE(), CURRENT_TIMESTAMP(),LOCALTIME()
FROM DUAL;

# 2.查询员工号,姓名,工资,以及工资提高百分之20%后的结果(new salary)
SELECT employee_id,last_name,salary,salary*1.2 "new salary"
FROM employees;
1

# 3.将员工的姓名按首字母排序,并写出姓名的长度(length)
SELECT last_name, LENGTH(last_name)
FROM employees
ORDER BY last_name;

# 4.查询员工id,last_name,salary,并作为一个列输出,别名为OUT_PUT
SELECT CONCAT(employee_id,',',last_name,',',salary) "OUT PUT"
FROM employees
# CONCAT连接字符串

# 5.查询公司各员工工作的年数、工作的天数,并按工作年数的降序排序
SELECT employee_id, ROUND(DATEDIFF(CURDATE(),hire_date)/365) "worked_years", DATEDIFF(CURDATE(),hire_date) "worked_days"
FROM employees
ORDER BY worked_years DESC

# 或者使用TO_DAYS(CURDATE())-TO_DAYS(CURDATE(hire_date))代表共工作天数


# 6.查询员工姓名,hire_date , department_id,满足以下条件:
#雇用时间在1997年之后,department_id 为80 或 90 或110, commission_pct不为空
SELECT last_name, hire_date, department_id
FROM employees
WHERE department_id IN (80,90,110)
AND commission_pct IS NOT NULL
#and hire_date >= '1997-01-01' #存在着隐式转换
#and date_format(hire_date,'%Y') >= '1997'; #显式转换,优化只用y
AND hire_date >= STR_TO_DATE('1997-01-01','%Y-%m-%d');# 显式转换操作,解析,字符串转日期



# 7.查询公司中入职超过10000天的员工姓名、入职时间
SELECT last_name, hire_date
FROM employees
WHERE DATEDIFF(CURDATE(),hire_date) >= 10000;

# 8.做一个查询,产生下面的结果
# earns  monthly but wants  
SELECT CONCAT(last_name,' earns ',salary, ' monthly but wants ',salary * 3) "Dream Salary"
FROM employees;
#小数优化一下,截断TRUNCATE()
SELECT CONCAT(last_name,' earns ',TRUNCATE(salary,0), ' monthly but wants ',TRUNCATE(salary * 3,0)) "Dream Salary"
FROM employees;

# 9.使用case-when,按照下面的条件:
/*job                  grade
AD_PRES              	A
ST_MAN               	B
IT_PROG              	C
SA_REP               	D
ST_CLERK             	E

产生下面的结果:
*/

SELECT last_name "Last_name",job_id "Job_id",CASE job_id WHEN 'AD_PRES' THEN 'A'
							 WHEN 'ST_MAN' THEN 'B'
							 WHEN 'IT_PROG' THEN 'C'
							 WHEN 'SA_REP' THEN 'D'
							 WHEN 'ST_CLERK' THEN 'E'
							 END "Grade"
FROM employees;	

SELECT last_name "Last_name",job_id "Job_id",CASE job_id WHEN 'AD_PRES' THEN 'A'
							 WHEN 'ST_MAN' THEN 'B'
							 WHEN 'IT_PROG' THEN 'C'
							 WHEN 'SA_REP' THEN 'D'
							 WHEN 'ST_CLERK' THEN 'E'
							 ELSE "undefined" END "Grade"
FROM employees;	

6. 聚合函数

#1.where子句可否使用组函数进行过滤?  No!

#2.查询公司员工工资的最大值,最小值,平均值,总和
SELECT MAX(salary) max_sal ,MIN(salary) mim_sal,AVG(salary) avg_sal,SUM(salary) sum_sal
FROM employees;

#3.查询各job_id的员工工资的最大值,最小值,平均值,总和
SELECT MAX(salary) max_sal ,MIN(salary) mim_sal,AVG(salary) avg_sal,SUM(salary) sum_sal
FROM employees
GROUP BY job_id

#4.选择具有各个job_id的员工人数
SELECT job_id,COUNT(*)
FROM employees
GROUP BY job_id;

# 5.查询员工最高工资和最低工资的差距(DIFFERENCE)  #DATEDIFF
SELECT MAX(salary) - MIN(salary) "DIFFERENCE"
FROM employees;


# 6.查询各个管理者手下员工的最低工资,其中最低工资不能低于6000,没有管理者的员工不计算在内
SELECT manager_id,MIN(salary)
FROM employees
WHERE manager_id IS NOT NULL
GROUP BY manager_id
HAVING MIN(salary) > 6000


# 7.查询所有部门的名字,location_id,员工数量和平均工资,并按平均工资降序 
SELECT d.department_name,d.location_id,COUNT(employee_id),AVG(salary)
FROM departments d LEFT JOIN employees e
ON d.`department_id` = e.`department_id`
GROUP BY department_name,location_id  
# !count(*)的话,部门就算没有人,也会出一条记录!
#?? group by 两个怎么理解?
# 答:同一部门同个department id同一组


# 8.查询每个工种、每个部门的部门名、工种名和最低工资 
SELECT d.department_name,e.job_id,MIN(salary)
FROM departments d LEFT JOIN employees e
ON d.`department_id` = e.`department_id`
GROUP BY department_name,job_id

7. 子查询


# 第09章_子查询的课后练习



#1.查询和Zlotkey相同部门的员工姓名和工资
SELECT last_name,salary
FROM employees
WHERE department_id IN (
			SELECT department_id
			FROM employees
			WHERE last_name = 'Zlotkey'
			);
#!如果一个人的话=可以,多个人用In

#2.查询工资比公司平均工资高的员工的员工号,姓名和工资。
SELECT last_name,salary
FROM employees
WHERE salary > (
		SELECT AVG(salary)
		FROM employees
		);


#3.选择工资大于所有JOB_ID = 'SA_MAN'的员工的工资的员工的last_name, job_id, salary
SELECT last_name,job_id,salary
FROM employees
WHERE salary > ALL(
		SELECT salary
		FROM employees
		WHERE job_id = 'SA_MAN'
		);



#4.查询和姓名中包含字母u的员工在相同部门的员工的员工号和姓名
SELECT last_name,employee_id
FROM employees
WHERE department_id IN (
		SELECT DISTINCT department_id
		FROM employees
		WHERE last_name LIKE '%u%'
		);



#5.查询在部门的location_id为1700的部门工作的员工的员工号

SELECT employee_id
FROM employees
WHERE department_id IN (SELECT department_id
			FROM departments
			WHERE location_id = 1700
			);


#6.查询管理者是King的员工姓名和工资
SELECT last_name,salary,manager_id
FROM employees
WHERE manager_id IN (
			SELECT employee_id
			FROM employees
			WHERE last_name = 'King'
			);




#7.查询工资最低的员工信息: last_name, salary
SELECT last_name,salary
FROM employees
WHERE salary = (
		SELECT MIN(salary)
		FROM employees
		);



#8.查询平均工资最低的部门信息
#方式1:
SELECT d.*,(SELECT AVG(salary) FROM employees WHERE department_id = d.`department_id`) avg_sal
FROM departments d
WHERE department_id = (
			SELECT department_id
			FROM employees
			GROUP BY department_id
			HAVING AVG(salary ) = (
						SELECT MIN(avg_sal)
						FROM (
							SELECT AVG(salary) avg_sal
							FROM employees
							GROUP BY department_id
							) t_dept_avg_sal

						)
			);



#方式2:用ALL替换找最小
SELECT d.*,(SELECT AVG(salary) FROM employees WHERE department_id = d.`department_id`) avg_sal
FROM departments d
WHERE department_id = (
			SELECT department_id
			FROM employees
			GROUP BY department_id
			HAVING AVG(salary ) <= ALL(
						SELECT AVG(salary)
						FROM employees
						GROUP BY department_id
						)
			);


#方式3: LIMIT。排序,用limit取第一个,和Min的结果一样
SELECT d.*,(SELECT AVG(salary) FROM employees WHERE department_id = d.`department_id`) avg_sal
FROM departments d
WHERE department_id = (
			SELECT department_id
			FROM employees
			GROUP BY department_id
			HAVING AVG(salary ) =(
						SELECT AVG(salary) avg_sal
						FROM employees
						GROUP BY department_id
						ORDER BY avg_sal ASC
						LIMIT 1		
						)
			);

#方式4:构建一张新的表t_dept_avg_sal
SELECT d.*,(SELECT AVG(salary) FROM employees WHERE department_id = d.`department_id`) avg_sal
FROM departments d,(
		SELECT department_id,AVG(salary) avg_sal
		FROM employees
		GROUP BY department_id
		ORDER BY avg_sal ASC
		LIMIT 0,1
		) t_dept_avg_sal
WHERE d.`department_id` = t_dept_avg_sal.department_id

		
#9.查询平均工资最低的部门信息和该部门的平均工资(相关子查询)
#方式1:第一行的department_id = d.`department_id`可以直接用
SELECT d.*,(SELECT AVG(salary) FROM employees WHERE department_id = d.`department_id`) avg_sal
FROM departments d
WHERE department_id = (
			SELECT department_id
			FROM employees
			GROUP BY department_id
			HAVING AVG(salary ) = (
						SELECT MIN(avg_sal)
						FROM (
							SELECT AVG(salary) avg_sal
							FROM employees
							GROUP BY department_id
							) t_dept_avg_sal

						)
			);
			
#下面着三种方法跟上面一样		
#方式2:



#方式3: LIMIT



#方式4:



#10.查询平均工资最高的 job 信息

#方式1:
SELECT *
FROM jobs
WHERE job_id = (
		SELECT job_id
		FROM employees
		GROUP BY job_id
		HAVING AVG(salary) = (
					SELECT MAX(avg_sal)
					FROM (
						SELECT AVG(salary) avg_sal
						FROM employees
						GROUP BY job_id
						) t_job_avg_sal
					)
		);

# 后面三种方式和上面第九题一样
#方式2:


#方式3:


#方式4:
SELECT j.*
FROM jobs j,(
		SELECT job_id,AVG(salary) avg_sal
		FROM employees
		GROUP BY job_id
		ORDER BY avg_sal DESC
		LIMIT 0,1		
		) t_job_avg_sal
WHERE j.job_id = t_job_avg_sal.job_id
		
#11.查询平均工资高于公司平均工资的部门有哪些?

SELECT department_id
FROM employees
WHERE department_id IS NOT NULL
GROUP BY department_id
HAVING AVG(salary) > (
			SELECT AVG(salary)
			FROM employees
			);


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

#方式1:自连接  xxx worked for yyy
SELECT DISTINCT mgr.employee_id,mgr.last_name,mgr.job_id,mgr.department_id
FROM employees emp JOIN employees mgr
ON emp.manager_id = mgr.employee_id;

#方式2:子查询

SELECT employee_id,last_name,job_id,department_id
FROM employees
WHERE employee_id IN (
			SELECT DISTINCT manager_id
			FROM employees
			);

#方式3:使用EXISTS
SELECT employee_id,last_name,job_id,department_id
FROM employees e1
WHERE EXISTS (
	       SELECT *
	       FROM employees e2
	       WHERE e1.`employee_id` = e2.`manager_id`
	     );

	
#13.各个部门中 最高工资中最低的那个部门的 最低工资是多少?

#方式1:
SELECT MIN(salary)
FROM employees
WHERE department_id = (
			SELECT department_id
			FROM employees
			GROUP BY department_id
			HAVING MAX(salary) = (
						SELECT MIN(max_sal)
						FROM (
							SELECT MAX(salary) max_sal
							FROM employees
							GROUP BY department_id
							) t_dept_max_sal
						)
			);

SELECT *
FROM employees
WHERE department_id = 10;

#方式2:
SELECT MIN(salary)
FROM employees
WHERE department_id = (
			SELECT department_id
			FROM employees
			GROUP BY department_id
			HAVING MAX(salary) <= ALL (
						SELECT MAX(salary)
						FROM employees
						GROUP BY department_id
						)
			);

#方式3:
SELECT MIN(salary)
FROM employees
WHERE department_id = (
			SELECT department_id
			FROM employees
			GROUP BY department_id
			HAVING MAX(salary) = (
						SELECT MAX(salary) max_sal
						FROM employees
						GROUP BY department_id
						ORDER BY max_sal ASC
						LIMIT 0,1
						)
			);
			
#方式4:
SELECT MIN(salary)
FROM employees e,(
		SELECT department_id,MAX(salary) max_sal
		FROM employees
		GROUP BY department_id
		ORDER BY max_sal ASC
		LIMIT 0,1
		) t_dept_max_sal
WHERE e.department_id = t_dept_max_sal.department_id


#14.查询平均工资最高的部门的 manager 的详细信息: last_name, department_id, email, salary
#方式1:
SELECT last_name, department_id, email, salary
FROM employees
WHERE employee_id = ANY (
			SELECT DISTINCT manager_id
			FROM employees
			WHERE department_id = (
						SELECT department_id
						FROM employees
						GROUP BY department_id
						HAVING AVG(salary) = (
									SELECT MAX(avg_sal)
									FROM (
										SELECT AVG(salary) avg_sal
										FROM employees
										GROUP BY department_id
										) t_dept_avg_sal
									)
						)
			);

#方式2:
SELECT last_name, department_id, email, salary
FROM employees
WHERE employee_id = ANY (
			SELECT DISTINCT manager_id
			FROM employees
			WHERE department_id = (
						SELECT department_id
						FROM employees
						GROUP BY department_id
						HAVING AVG(salary) >= ALL (
								SELECT AVG(salary) avg_sal
								FROM employees
								GROUP BY department_id
								)
						)
			);

#方式3:
SELECT last_name, department_id, email, salary
FROM employees
WHERE employee_id IN (
			SELECT DISTINCT manager_id
			FROM employees e,(
					SELECT department_id,AVG(salary) avg_sal
					FROM employees
					GROUP BY department_id
					ORDER BY avg_sal DESC
					LIMIT 0,1
					) t_dept_avg_sal
			WHERE e.`department_id` = t_dept_avg_sal.department_id
			);


#15. 查询部门的部门号,其中不包括job_id是"ST_CLERK"的部门号
#方式1:
SELECT department_id
FROM departments
WHERE department_id NOT IN (
			SELECT DISTINCT department_id
			FROM employees
			WHERE job_id = 'ST_CLERK'
			);

#方式2:
SELECT department_id
FROM departments d
WHERE NOT EXISTS (
		SELECT *
		FROM employees e
		WHERE d.`department_id` = e.`department_id`
		AND e.`job_id` = 'ST_CLERK'
		);



#16. 选择所有没有管理者的员工的last_name

SELECT last_name
FROM employees emp
WHERE NOT EXISTS (
		SELECT *
		FROM employees mgr
		WHERE emp.`manager_id` = mgr.`employee_id`
		);

#17.查询员工号、姓名、雇用时间、工资,其中员工的管理者为 'De Haan'
#方式1:
SELECT employee_id,last_name,hire_date,salary
FROM employees
WHERE manager_id IN (
		SELECT employee_id
		FROM employees
		WHERE last_name = 'De Haan'
		);

#方式2:
SELECT employee_id,last_name,hire_date,salary
FROM employees e1
WHERE EXISTS (
		SELECT *
		FROM employees e2
		WHERE e1.`manager_id` = e2.`employee_id`
		AND e2.last_name = 'De Haan'
		); 


#18.查询各部门中工资比本部门平均工资高的员工的员工号, 姓名和工资(相关子查询)

#方式1:使用相关子查询
SELECT last_name,salary,department_id
FROM employees e1
WHERE salary > (
		SELECT AVG(salary)
		FROM employees e2
		WHERE department_id = e1.`department_id`
		);

#方式2:在FROM中声明子查询
SELECT e.last_name,e.salary,e.department_id
FROM employees e,(
		SELECT department_id,AVG(salary) avg_sal
		FROM employees
		GROUP BY department_id) t_dept_avg_sal
WHERE e.department_id = t_dept_avg_sal.department_id
AND e.salary > t_dept_avg_sal.avg_sal


#19.查询每个部门下的部门人数大于 5 的部门名称(相关子查询)

SELECT department_name
FROM departments d
WHERE 5 < (
	   SELECT COUNT(*)
	   FROM employees e
	   WHERE d.department_id = e.`department_id`
	  );


#20.查询每个国家下的部门个数大于 2 的国家编号(相关子查询)

SELECT * FROM locations;

SELECT country_id
FROM locations l
WHERE 2 < (
	   SELECT COUNT(*)
	   FROM departments d
	   WHERE l.`location_id` = d.`location_id`
	 );

/* 
子查询的编写技巧(或步骤):① 从里往外写  ② 从外往里写

如何选择?
① 如果子查询相对较简单,建议从外往里写。一旦子查询结构较复杂,则建议从里往外写
② 如果是相关子查询的话,通常都是从外往里写。

*/

你可能感兴趣的:(MySQL学习,#,MySQL练习,sql)