mySQL筆記(七):子查詢
阿新 • • 發佈:2020-02-20
#進階7:子查詢 /* 說明:當一個查詢語句中又嵌套了另一個完整的select語句,則被巢狀的select語句稱為子查詢或內查詢 外面的select語句稱為主查詢或外查詢。 分類: 按子查詢出現的位置進行分類: 1、select後面 要求:子查詢的結果為單行單列(標量子查詢) 2、from後面 結果可以為多行多列 3、where或having後面 子查詢的結果必須為單列 單行子查詢 多行子查詢 4、exists後面 子查詢結果必須為單列(相關子查詢) 特點: 1、子查詢放在條件中,要求必須放在條件的右側 2、子查詢一般放在小括號中 3、子查詢的執行優於主查詢 4、單行子查詢對應了 單行操作符:> < >= <= = <> 多行子查詢對應了 多行操作符:any/some all in */ #一、放在where或having後面 #一)單行子查詢(標量子查詢) #案例1:誰的工資比 Abel 高? 1、查詢Abel的工資 SELECT `salary` FROM `employees` WHERE `last_name` = 'Abel'; 2、查詢員工的細膩,滿足工資>1中的結果 SELECT * FROM `employees` WHERE `salary`>( SELECT `salary` FROM `employees` WHERE `last_name` = 'Abel' ); #案例2:返回job_id與141號員工相同,salary比143號員工多的員工姓名,job_id 和工資 SELECT `job_id` FROM `employees` WHERE `employee_id` = 141; SELECT `salary` FROM `employees` WHERE `employee_id` = 143; 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 ); #案例3:返回公司工資最少的員工的last_name,job_id和salary SELECT `last_name`,`salary` FROM `employees` WHERE `salary` = ( SELECT MIN(`salary`) FROM `employees` ); #案例4:查詢最低工資大於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 ); -- ##########################練習 #1、查詢和 Zlotkey 相同部門的員工姓名和工資 SELECT `last_name`,`salary` FROM `employees` WHERE `department_id` = ( SELECT `department_id` FROM `employees` WHERE `last_name` = 'Zlotkey' ); #2、查詢工資比公司平均工資高的員工的員工號,姓名和工資。 SELECT `employee_id`,`last_name`,`salary` FROM `employees` WHERE `salary`>( SELECT AVG(`salary`) FROM `employees` ); -- ########################### #二)多行子查詢 /* in:判斷某欄位是否在指定列表內 x in(10,30,50) any/some:判斷某欄位的值是否滿足其中任意一個 x>any(10,50),大於任意一個 x>min() x=any(10,50) x in(10,50)二者等價 all:判斷某欄位的值是否滿足裡面所有的 x >all(10,50),大於所有的 x >max() */ #案例1:返回location_id是1400或1700的部門中的所有員工姓名 SELECT `last_name` FROM `employees` WHERE `department_id` IN( SELECT DISTINCT `department_id` FROM `departments` WHERE `location_id` IN(1400,1700) ); #案例2:返回其它部門中比job_id為‘IT_PROG’部門任一工資低的員工的員工號、姓名、job_id 以及salary SELECT `employee_id`,`salary` FROM `employees` WHERE `salary` <ANY( SELECT `salary` FROM `employees` WHERE `job_id` = 'IT_PROG' ); 等價於 SELECT `employee_id`,`salary` FROM `employees` WHERE `salary` <( SELECT MAX(`salary`) FROM `employees` WHERE `job_id` = 'IT_PROG' ); #案例3:返回其它部門中比job_id為‘IT_PROG’部門所有工資都低的員工的員工號、姓名、job_id 以及salary SELECT `employee_id`,`salary` FROM `employees` WHERE `salary` <ALL( SELECT `salary` FROM `employees` WHERE `job_id` = 'IT_PROG' ); 等價於 SELECT `employee_id`,`salary` FROM `employees` WHERE `salary` <( SELECT MIN(`salary`) FROM `employees` WHERE `job_id` = 'IT_PROG' ); #二、放在select後面 #案例;查詢部門編號是50的員工個數 SELECT( SELECT COUNT(*) FROM `employees` WHERE `department_id` = 50 ) 個數; #三、放在from後面(表子查詢) #案例:查詢每個部門的平均工資的工資級別 #1、每個部門的平均工資 SELECT `department_id`,AVG(`salary`) FROM `employees` GROUP BY `department_id`; #將1和`job_grades`兩表連線 SELECT `department_id`,`grade_level` FROM `job_grades` g JOIN (SELECT AVG(`salary`) ag,`department_id` FROM `employees` GROUP BY `department_id`) dep_ag ON dep_ag.ag BETWEEN g.`lowest_sal` AND g.`highest_sal`; #四、放在exists後面 #案例1 :查詢有無名字叫“張三丰”的員工資訊 SELECT EXISTS( SELECT * FROM `employees` WHERE `last_name` = '張三丰' ) 有無張三丰;