Mysql学习笔记(010)-子查询

会有一股神秘感。 提交于 2020-02-06 17:37:51

子查询

  1 #进阶7子查询
  2 /*
  3 含义:
  4 出现在其他语句中的select语句,称为子查询或内查询
  5 外部的查询语句,称为主查询或外查询
  6 
  7 分类:
  8 按子查询出现的位置:
  9     select后面
 10         仅仅支持标量子查询
 11     from后面:
 12         支持表子查询
 13     where或having后面☆
 14         标量子查询(单行)√
 15         列子查询(多行)√
 16         行子查询(用的少)
 17     exists后面(相关子查询)
 18         表子查询
 19 按结果集的行列数不同:
 20     标量子查询(结果集只有一行一列)
 21     列子查询(结果集只有一列多行)
 22     行子查询(结果集只有一行多列)
 23     表子查询(结果集一般为多行多列)
 24 
 25 */
 26 
 27 #一、where或having后面
 28 /*
 29 1、标量子查询(单行子查询)
 30 2、列子查询(多行子查询)
 31 3、行子查询(多列多行)
 32 特点:
 33 ①子查询都会放在小括号内
 34 ②子查询一般放在条件的右侧
 35 ③标量子查询,一般搭配着单行操作符使用
 36 > < >= <= = <>
 37 
 38 列子查询:一般搭配多行操作符使用
 39 in、any/some、all
 40 
 41 ④子查询的执行优于主查询执行,主查询的条件用到的了子查询的结果
 42 
 43 */
 44 #1.标量子查询
 45 #案例1:谁的工资比Abel高?
 46 #①查询Abel的工资
 47 SELECT salary
 48 FROM employees                       
 49 WHERE last_name = 'Abel'
 50 #②查询员工的信息,满足salary>①结果
 51 SELECT * 
 52 FROM employees
 53 WHERE salary>(
 54     SELECT salary
 55     FROM employees
 56     WHERE last_name = 'Abel'
 57 )
 58 
 59 #案例2:返回job_id与141号员工相同,salary比143号员工多的员工姓名,job_id和工资
 60 #①查新141号员工的job_id
 61 SELECT    job_id
 62 FROM employees
 63 WHERE employee_id =141
 64 
 65 #②查询143号员工的salary
 66 SELECT salary
 67 FROM employees
 68 WHERE employee_id =143
 69 
 70 #③查询员工的姓名,job_id和工资,要求job_id=①并且salary>②
 71 SELECT last_name,job_id,salary
 72 FROM employees
 73 WHERE job_id=(
 74     SELECT    job_id
 75     FROM employees
 76     WHERE employee_id =141
 77 ) AND salary >(
 78     SELECT salary
 79     FROM employees
 80     WHERE employee_id =143
 81 )
 82 
 83 #案例3:返回公司工资最少的员工的last_name,job_id和salary
 84 #①查询公司的最低工资
 85 SELECT MIN(salary)
 86 FROM employees
 87 
 88 #②查询last_name,job_id和salary,要求salary=①
 89 SELECT last_name,job_id,salary
 90 FROM employees
 91 WHERE salary=(
 92     SELECT MIN(salary)
 93     FROM employees
 94 )
 95 
 96 #案例4:查询最低工资大于50号部门最低工资的部门id和其最低工资(使用having筛选)
 97 #①查询50号部门的最低工资
 98 SELECT MIN(salary)
 99 FROM employees
100 WHERE department_id=50
101 
102 #②查询每个部门的最低工资
103 SELECT MIN(salary)
104 FROM employees
105 GROUP BY department_id
106 
107 #③在②基础上筛选,满足min(salary)>①
108 SELECT MIN(salary),department_id
109 FROM employees
110 GROUP BY department_id
111 HAVING MIN(salary) >(
112     SELECT MIN(salary)
113     FROM employees
114     WHERE department_id=50
115 )
116 
117 
118 #非法使用标量子查询(》只能搭配标量子查询,必须是一行一列)
119 SELECT MIN(salary),department_id
120 FROM employees
121 GROUP BY department_id
122 HAVING MIN(salary) >(
123     SELECT salary#
124     FROM employees
125     WHERE department_id=50
126 )
127 
128 #2.列子查询(多行子查询)
129 #案例1:返回location_id是1400或1700的部门中的所有员工姓名
130 #①查询location_id是1400或1700的部门编号
131 SELECT DISTINCT department_id
132 FROM departments
133 WHERE location_id IN(1400,1700)
134 
135 #②查询员工姓名,要去部门号是①列表中的某一个 not in等价于<> all
136 
137 SELECT last_name
138 FROM employees
139 WHERE department_id IN(
140     SELECT DISTINCT department_id
141     FROM departments
142     WHERE location_id IN(1400,1700)
143 )
144 #或
145 SELECT last_name
146 FROM employees
147 WHERE department_id=ANY(
148     SELECT DISTINCT department_id
149     FROM departments
150     WHERE location_id IN(1400,1700)
151 )
152 
153 #案例2:返回其它工种
154 +++++中比job_id为'IT_PROG'部门任一工资低的员工的员工号、姓名、job_id以及salary
155 #①查询job_id为'IT_PORG'部门任一工资
156 SELECT DISTINCT salary
157 FROM employees
158 WHERE job_id='IT_PORG'
159 
160 #②查询员工号、姓名、job_id以及salary,salary<①的任意一个
161 SELECT last_name,employee_id,job_id,salary
162 FROM employees
163 WHERE salary<ANY(
164     SELECT DISTINCT salary
165     FROM employees
166     WHERE job_id='IT_PORG'
167 ) AND job_id <> 'IT_PROG';
168 
169 #或
170 SELECT last_name,employee_id,job_id,salary
171 FROM employees
172 WHERE salary <(
173     SELECT MAX(salary)
174     FROM employees
175     WHERE job_id='IT_PORG'
176 ) AND job_id <> 'IT_PROG';
177 
178 
179 #案例3:返回其他部门中比job_idwei'IT_PROG'部门所有工资都低的员工的员工号、姓名、job_id以及salary
180 SELECT last_name,employee_id,job_id,salary
181 FROM employees
182 WHERE salary <ALL(
183     SELECT DISTINCT salary
184     FROM employees
185     WHERE job_id='IT_PORG'
186 ) AND job_id <> 'IT_PROG';
187 
188 #或
189 SELECT last_name,employee_id,job_id,salary
190 FROM employees
191 WHERE salary <(
192     SELECT MIN(salary)
193     FROM employees
194     WHERE job_id='IT_PORG'
195 ) AND job_id <> 'IT_PROG';
196 
197 #3.行子查询(结果集是一行多列或多行多列)
198 #多个子结果集都是等于号
199 #案例:查询员工编号最小并且工资最高的员工信息
200 
201 SELECT * FROM employees
202 WHERE (employee_id,salary)=(
203     SELECT MIN(employee_id),MAX(salary)
204     FROM employees
205 );
206 
207 #①查询最小的员工编号
208 SELECT MIN(employee_id)
209 FROM employees
210 
211 #②查询最高工资
212 SELECT MAX(salary)
213 FROM employees
214 
215 #③查询员工信息
216 SELECT * FROM employees
217 WHERE employee_id=(
218     SELECT MIN(employee_id)
219     FROM employees
220 
221 ) AND salary=(
222     SELECT MAX(salary)
223     FROM employees
224 
225 )
226 
227 
228 #二、select后面
229 
230 #案例:查询每个部门的员工个数
231 SELECT d.*,(
232     SELECT COUNT(*)
233     FROM employees d
234     WHERE e.department_id= d.department_id
235 ) 个数
236 FROM department_id;
237 
238 
239 #案例2:查询员工号=102的部门名
240 SELECT (
241     SELECT department_name
242     FROM departments d
243     INNER JOIN employees e
244     ON d.department_id = e.department_id
245     WHERE e.employee_id=102
246 ) 部门名;
247 
248 
249 #三、from后面
250 /*
251 将子查询结果充当一张表,要求必须起别名
252 */
253 
254 #案例:查询每个部门的平均工资的工资等级
255 #①查询每个部门的平均工资
256 SELECT AVG(salary),department_id
257 FROM employees
258 GROUP BY department_id
259 
260 #②连接①的结果集和jobgrades表,筛选条件平均工资between lowest_sal and highest_sal
261 
262 SELECT ag_dep.*,'grade_level'
263 FROM (
264     SELECT AVG(salary) ag,department_id
265     FROM employees
266     GROUP BY department_id
267 ) ag_dep
268 INNER JOIN job_grades g
269 ON ag_dep.ag BETWEEN lowest_sal AND highest_sal
270 
271 
272 #四、exists后面(相关子查询)
273 /*
274 语法:
275 exists(完整的查询语句)
276 结果:
277 1或0
278 
279 */
280 SELECT EXISTS(SELECT employee_id FROM employees);
281 
282 
283 #案例1:查询有员工的部门名
284 
285 #in
286 SELECT department_name
287 FROM departments d
288 WHERE d.`department_id` IN(
289     SELECT department_id
290     FROM employees e
291     WHERE d.`department_id`=e.`department_id`
292     
293 )
294 
295 
296 #exist
297 
298 SELECT department_name
299 FROM departments d
300 WHERE EXISTS(
301     SELECT * 
302     FROM employees e
303     WHERE d.department_id=e.`department_id`
304 );
305 
306 
307 #案例2:查询没有女朋友的男神信息
308 #in
309 USE girls;
310 SELECT bo.*
311 FROM boys bo
312 WHERE bo.id NOT IN (
313     SELECT boyfriend_id
314     FROM beauty
315     
316 )
317 
318 
319 #exists
320 SELECT bo.*
321 FROM boys bo
322 WHERE NOT EXISTS(
323     SELECT boyfriend_id
324     FROM beauty b
325     WHERE bo.`id`=b.`boyfriend_id`
326     
327 );

 

练习

#1.查询和Zlotkey相同部门的员工姓名和工资

#①查询和Zlotkey的部门
SELECT deparment_id
FROM employees
WHERE last_name='Zlotkey'
#②查询部门号=①的姓名和工资
SELECT last_name,salary
FROM employees
WHERE department_id = (
	SELECT department_id
	FROM employees
	WHERE last_name='Zlotkey'
)

#2查询工资比公司平均工资高的员工的员工号,姓名和工资

#①查询平均工资
SELECT AVG(salary)
FROM employees

#②查询工资>①的员工号,姓名和工资

SELECT last_name,employee_id,salary
FROM employees
WHERE salary >(
	SELECT AVG(salary)
	FROM employees

)


#3. 查询各部门中工资比本部门平均工资高的员工的员工号,姓名和工资
#①查询各部门的平均工资
SELECT AVG(salary),department_id
FROM employees
GROUP BY department_id

#②连接①结果集和employees表,进行筛选
SELECT employee_id,last_name,salary,e.department_id
FROM employees e
INNER JOIN (
	SELECT AVG(salary) ag,department_id
	FROM employees
	GROUP BY department_id

) ag_dep
ON e.department_id = ag_dep.department_id
WHERE salary>ag_dep.ag
 
#4. 查询和姓名中包含字母u的员工在相同部门的员工的员工的号和姓名 
#①查询和姓名中包含字母u的员工的部门

SELECT DISTINCT department_id
FROM employees
WHERE last_name LIKE '%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的部门工作的员工的员工号 
#①查询location_id为1700的部门
SELECT DISTINCT department_id
FROM departments
WHERE location_id=1700;

#②查询部门号=①中的任意一个的员工号
SELECT employee_id
FROM employees e
WHERE department_id =ANY(
SELECT DISTINCT d.`department_id`
FROM departments d
WHERE location_id=1700;
)

#6. 查询管理者是king的员工姓名和工资 
#①查询姓名为king的员工编号
SELECT employee_id
FROM employees
WHERE last_name='king'

#②查询哪个员工的manager_id=①
SELECT last_name,salary
FROM employees
WHERE manager_id IN(
SELECT employee_id
FROM employees
WHERE last_name='king'

)

#7. 查询工资最高的员工的姓名,要求first_name和last_name显示为一列,列名为姓.名
#① 查询最高工资
SELECT MAX(salary)
FROM employees

#②查询工资=①的姓.名
SELECT CONCAT(first_name,last_name) "姓.名"
FROM employees
WHERE salary =(
	SELECT MAX(salary)
	FROM employees
)

  

小结

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!