1. 程式人生 > 實用技巧 >lyt經典版MySQL基礎——進階7:子查詢

lyt經典版MySQL基礎——進階7:子查詢

  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 #一、where或having後面 27 /* 28 1.標量子查詢(單行子查詢) 29 2.列子查詢(多行子查詢) 30 3.行子查詢(多列多行) 31 32 特點: 33 (1)子查詢放在小括號內 34 (2)子查詢一般放在條件的右側 35 (3)標量子查詢,一般搭配著單行操作符使用 36 > < >= <= <>
37 38 列子查詢,一般搭配著多行操作符使用 39 in、any/some、all 40 (4)子查詢的執行優先於主查詢執行,主查詢的條件用到了子查詢的結果 41 */ 42 43 #1.標量子查詢 44 #案例1:誰的工資比Abel高? 45 #(1)查詢Abel的工資 46 SELECT salary 47 FROM employees 48 WHERE last_name='Abel'; 49 #(2)查詢員工的資訊,滿足salary>(1)的結果 50 SELECT * 51 FROM employees 52 WHERE salary>(
53 SELECT salary 54 FROM employees 55 WHERE last_name='Abel' 56 ); 57 #案例2:返回job_id與141號員工相同,salary比143號員工多的員工姓名,job_id和工資 58 #(1)查詢141號員工的job_id 59 SELECT job_id 60 FROM employees 61 WHERE employee_id='141' 62 #(2)查詢143號員工的salary 63 SELECT salary 64 FROM employees 65 WHERE employee_id='143' 66 #(3)查詢員工姓名,job_id和工資,要求job_id=(1)並且salary>(2) 67 SELECT last_name,job_id,salary 68 FROM employees WHERE job_id=( 69 SELECT job_id 70 FROM employees 71 WHERE employee_id='141' 72 )AND salary>( 73 SELECT salary 74 FROM employees 75 WHERE employee_id='143' 76 ); 77 #案例3:返回公司工資最少的員工的last_name,job_id和salary 78 #(1)查詢公司的最低工資 79 SELECT MIN(salary) 80 FROM employees 81 #(2)查詢last_name,job_id和salary,要求salary=(1) 82 SELECT last_name,job_id,salary 83 FROM employees 84 WHERE salary=( 85 SELECT MIN(salary) 86 FROM employees 87 ); 88 #案例4:查詢最低工資大於50號部門最低工資的部門id和其最低工資 89 #(1)查詢50號部門的最低工資 90 SELECT MIN(salary) 91 FROM employees 92 WHERE department_id='50' 93 #(2)查詢每個部門的最低工資 94 SELECT department_id,MIN(salary) '最低工資' 95 FROM employees 96 GROUP BY department_id 97 #(3)在(2)的基礎上篩選,滿足min(salary)>(1) 98 SELECT department_id,MIN(salary) '最低工資' 99 FROM employees 100 GROUP BY department_id 101 HAVING 最低工資>( 102 SELECT MIN(salary) 103 FROM employees 104 WHERE department_id='50' 105 ); 106 107 #非法使用標量子查詢——子查詢的結果不是一行一列 108 SELECT department_id,MIN(salary) '最低工資' 109 FROM employees 110 GROUP BY department_id 111 HAVING 最低工資>( 112 SELECT salary 113 FROM employees 114 WHERE department_id='50' 115 ); 116 117 118 #2.列子查詢(多行子查詢) 119 #案例1:返回location_id是1400或1700的部門中的所有員工姓名 120 #(1)查詢location_id是1400或1700的部門編號 121 SELECT DISTINCT department_id 122 FROM departments 123 WHERE location_id IN(1400,1700) 124 #(2)查詢員工姓名,要求部門號是(1)列表中的某一個 125 SELECT last_name 126 FROM employees 127 WHERE department_id IN( 128 SELECT DISTINCT department_id 129 FROM departments 130 WHERE location_id IN(1400,1700) 131 ); 132 #或 133 SELECT last_name 134 FROM employees 135 WHERE department_id =ANY( 136 SELECT DISTINCT department_id 137 FROM departments 138 WHERE location_id IN(1400,1700) 139 ); 140 #案例2:返回其他工種中比job_id為'IT_PROG'工種任一工資低的員工的 141 #員工號、姓名、job_id以及salary 142 #(1)查詢job_id為'IT_PROG'工種任一工資 143 SELECT salary 144 FROM employees 145 WHERE job_id='IT_PROG' 146 #(2)查詢員工號、姓名、job_id以及salary,salary<(1)中的任意一個 147 SELECT employee_id,last_name,job_id,salary 148 FROM employees 149 WHERE salary<ANY( 150 SELECT salary 151 FROM employees 152 WHERE job_id='IT_PROG' 153 )AND job_id <>'IT_PROG'; 154 #或 155 SELECT employee_id,last_name,job_id,salary 156 FROM employees 157 WHERE salary<( 158 SELECT MAX(salary) 159 FROM employees 160 WHERE job_id='IT_PROG' 161 )AND job_id <>'IT_PROG'; 162 #案例3:返回其他工種中比job_id為'IT_PROG'工種所有工資都低的員工的 163 #員工號、姓名、job_id以及salary 164 SELECT employee_id,last_name,job_id,salary 165 FROM employees 166 WHERE salary<ALL( 167 SELECT DISTINCT salary 168 FROM employees 169 WHERE job_id='IT_PROG' 170 )AND job_id <>'IT_PROG'; 171 #或 172 SELECT employee_id,last_name,job_id,salary 173 FROM employees 174 WHERE salary<( 175 SELECT DISTINCT MIN(salary) 176 FROM employees 177 WHERE job_id='IT_PROG' 178 )AND job_id <>'IT_PROG'; 179 180 #3.行子查詢(結果集一行多列或多行多列) 181 #案例:查詢員工編號最小並且工資最高的員工資訊 182 #(1)查詢最小的員工編號 183 SELECT MIN(employee_id) 184 FROM employees 185 #(2)查詢最高工資 186 SELECT MAX(salary) 187 FROM employees 188 #(3)查詢員工資訊 189 SELECT * FROM employees 190 WHERE employee_id=( 191 SELECT MIN(employee_id) 192 FROM employees 193 ) AND salary=( 194 SELECT MAX(salary) 195 FROM employees 196 ); 197 #或 198 SELECT * FROM employees 199 WHERE (employee_id,salary)=( 200 SELECT MIN(employee_id),MAX(salary) 201 FROM employees 202 ); 203 204 #二、select後面 205 /* 206 僅僅支援標量子查詢 207 */ 208 #案例:查詢每個部門的員工個數 209 SELECT d.*,( 210 SELECT COUNT(*) 211 FROM employees e 212 WHERE e.department_id=d.department_id 213 ) 個數 214 FROM departments d; 215 #案例2:查詢員工號=102的部門名 216 SELECT( 217 SELECT department_name 218 FROM departments d 219 INNER JOIN employees e ON d.department_id=e.department_id 220 WHERE e.employee_id='102' 221 ) 部門名; 222 223 #三、from後面 224 /* 225 將子查詢結果充當一張表,要求必須起別名 226 */ 227 #案例:查詢每個部門的平均工資的工資等級 228 #(1)查詢每個部門的平均工資 229 SELECT AVG(salary),department_id 230 FROM employees 231 GROUP BY department_id 232 #(2)連線(1)的結果集和job_grades表,篩選條件平均工資 233 SELECT ag_dep.*,grade_level 234 FROM ( 235 SELECT AVG(salary) ag,department_id 236 FROM employees 237 GROUP BY department_id 238 ) ag_dep 239 INNER JOIN job_grades ON ag_dep.ag BETWEEN lowest_sal AND highest_sal; 240 241 #四、exists後面(相關子查詢) 242 /* 243 語法: 244 exists(完整的查詢語句) 245 結果: 246 1或0 247 */ 248 SELECT EXISTS(SELECT employee_id FROM employees WHERE salary='30000'); 249 #案例1:查詢有員工的部門名 250 #in 251 SELECT department_name FROM departments 252 WHERE department_id IN( 253 SELECT department_id FROM employees 254 WHERE employee_id IS NOT NULL 255 ); 256 #exists 257 SELECT department_name FROM departments d 258 WHERE EXISTS ( 259 SELECT employee_id FROM employees e 260 WHERE d.department_id=e.department_id 261 ); 262 263 #案例2:查詢沒有女朋友的男神資訊 264 #in 265 SELECT * FROM boys 266 WHERE boys.id NOT IN ( 267 SELECT boyfriend_id FROM beauty 268 ); 269 #exists 270 SELECT * FROM boys bo 271 WHERE NOT EXISTS( 272 SELECT boyfriend_id FROM beauty b 273 WHERE bo.id=b.boyfriend_id 274 );