子查询
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 )
小结
来源:https://www.cnblogs.com/landerhu/p/12269381.html