MySQL_基礎_DQL數據查詢語言
阿新 • • 發佈:2018-07-18
location 執行 exists 分離 expr 簡單 提高 class 運算
查詢語法
語法: SELECT * | { [DISTINCT] column | expression [alias], ... } FROM table [[connect_type] JION table2 ON connect_condition] [WHERE condition] [GROUP BY columns] [HAVING condition] [ORDER BY columns (ASC | DESC)] [LIMIT { [offset,] row_count | row_count OFFSET offset }]; 語句順序: 查詢語句書寫順序:SELECT –> FROM -> JION -> ON -> WHERE -> GROUP BY -> HAVING -> ORDER BY -> LIMIT 查詢語句執行順序:FROM -> JION -> ON -> WHERE -> GROUP BY -> HAVING -> SELECT –> ORDER BY -> LIMIT
基本查詢
語法: SELECT * | { [DISTINCT] column | expression [alias], ... } FROM table;特點: 1、查詢列表可以是:表中的字段、常量值、表達式、函數 2、查詢的結果是一個虛擬的表格 案例: 1、查詢表中的單個字段 SELECT last_name FROM employees; 2、查詢表中的多個字段 SELECT last_name,salary,email FROM employees; 3、查詢表中的所有字段 SELECT * FROM employees; 4、查詢常量值 SELECT 100; SELECT ‘john‘;5、查詢表達式 SELECT 100%98; 6、查詢函數 SELECT VERSION(); 7、起別名,AS SELECT last_name AS 姓,first_name AS 名 FROM employees; SELECT last_name 姓,first_name 名 FROM employees; 8、消除重復數據,DISTINCT SELECT DISTINCT department_id FROM employees; 9、+號的作用 SELECT 100+90; # 兩個操作數都為數值型,則做加法運算 SELECT ‘john‘+90; # 一方為字符型,試圖轉換成數值型,轉換成功則做加法運算,轉換失敗則轉換成0再運算 SELECT null+10; # 一方為null,結果為null 10、字符串連接 SELECT CONCAT(‘a‘,‘b‘,‘c‘) AS 結果;
條件查詢
語法: SELECT * | { [DISTINCT] column | expression [alias], ... } FROM table [WHERE condition]; 分類: 1、條件運算符 > < = != <> >= <= # 判斷普通值 <=> # 安全等於,即可以判斷null值,又可以判斷普通值,與is null比較可讀較低 2、邏輯運算符 &&或AND # 邏輯並,兩個條件都為true,結果為true,反之為false ||或OR # 邏輯或,只要有一個條件為true,結果為true,反之為false !或NOT # 邏輯否,如果連接的條件本身為false,結果為true,反之為false 3、模糊查詢 LIKE # 模糊查詢,% 任意多個字符,_ 任意單個字符 BETWEEN AND # 在兩個值之間(包含邊界) IN # 等於值列表中的一個 IS (NOT) NULL # 判斷null值 案例: 1、按條件表達式篩選 案例1:查詢工資>12000的員工信息 SELECT * FROM employees WHERE salary>12000; 案例2:查詢部門編號不等於90號的員工名和部門編號 SELECT last_name,department_id FROM employees WHERE department_id<>90; 案例3:查詢沒有獎金的員工名和獎金率 SELECT last_name,commission_pct FROM employees WHERE commission_pct <=> NULL; 案例4:查詢工資為12000的員工信息 SELECT last_name,salary FROM employees WHERE salary <=> 12000; 2、按邏輯表達式篩選 案例1:查詢工資z在10000到20000之間的員工名、工資以及獎金 SELECT last_name,salary,commission_pct FROM employees WHERE salary>=10000 AND salary<=20000; 案例2:查詢部門編號不是在90到110之間,或者工資高於15000的員工信息 SELECT * FROM employees WHERE NOT(department_id>=90 AND department_id<=110) OR salary>15000; 3、模糊查詢 LIKE: 案例1:查詢員工名中包含字符a的員工信息 SELECT * FROM employees WHERE last_name LIKE ‘%a%‘; 案例2:查詢員工名中第三個字符為e,第五個字符為a的員工名和工資 SELECT last_name,salary FROM employees WHERE last_name LIKE ‘__e_a%‘; 案例3:查詢員工名中第二個字符為_的員工名 SELECT last_name FROM employees WHERE last_name LIKE ‘_\_%‘; SELECT last_name FROM employees WHERE last_name LIKE ‘_$_%‘ ESCAPE ‘$‘; BETWEEN AND: 案例1:查詢員工編號在100到120之間的員工信息 SELECT * FROM employees WHERE employee_id >= 100 AND employee_id<=120; SELECT * FROM employees WHERE employee_id BETWEEN 100 AND 120; IN: 案例1:查詢員工的工種編號是 IT_PROG、AD_VP、AD_PRES中的一個員工名和工種編號 SELECT last_name,job_id FROM employees WHERE job_id = ‘IT_PROT‘ OR job_id = ‘AD_VP‘ OR JOB_ID =‘AD_PRES‘; SELECT last_name,job_id FROM employees WHERE job_id IN( ‘IT_PROT‘ ,‘AD_VP‘,‘AD_PRES‘); IS (NOT) NULL: 案例1:查詢沒有獎金的員工名和獎金率 SELECT last_name,commission_pct FROM employees WHERE commission_pct IS NULL; 案例2:查詢有獎金的員工名和獎金率 SELECT last_name,commission_pct FROM employees WHERE commission_pct IS NOT NULL;
排序查詢
語法: SELECT * | { [DISTINCT] column | expression [alias], ... } FROM table [WHERE condition] [ORDER BY columns (ASC | DESC)]; 特點: 1、ASC升序(默認,可省略),DESC降序 2、ORDER BYy子句可以支持 單個字段、別名、表達式、函數、多個字段 3、ORDER BY子句在查詢語句的最後面,除了LIMIT子句 案例: 1、按單個字段排序 案例:查詢員工信息,要求先按工資降序 SELECT * FROM employees ORDER BY salary DESC; 2、按多個字段排序 案例:查詢員工信息,要求先按工資降序,再按employee_id升序 SELECT * FROM employees ORDER BY salary DESC,employee_id ASC; 3、添加篩選條件再排序 案例:查詢部門編號>=90的員工信息,並按員工編號降序 SELECT * FROM employees WHERE department_id>=90 ORDER BY employee_id DESC; 4、按表達式排序 案例:查詢員工信息 按年薪降序 SELECT *,salary*12*(1+IFNULL(commission_pct,0)) FROM employees ORDER BY salary*12*(1+IFNULL(commission_pct,0)) DESC; 5、按別名排序 案例:查詢員工信息 按年薪升序 SELECT *,salary*12*(1+IFNULL(commission_pct,0)) 年薪 FROM employees ORDER BY 年薪 ASC; 6、按函數排序 案例:查詢員工名,並且按名字的長度降序 SELECT LENGTH(last_name),last_name FROM employees ORDER BY LENGTH(last_name) DESC;
函數查詢
常用函數: 字符函數:LENGTH、CONCAT、SUBSTR、REPLACE、INSTR、TRIM、LPAD、RPAD、UPPER、LOWER... 數字函數:ROUND、CEIL、FLOOR、ABS、POWER、TRUNCATE、MOD.. 日期函數:NOW、CURDATE、CURTIME、YEAR、MONTH、DAY、HOUR、MINUTE、SECOND、STR_TO_DATE、DATE_FORMAT.. 流程控制函數:IFNULL、NULLIF、IF、CASE.. 其他函數:VERSION、DATABASE、USER.. 聚合函數:SUM、AVG、MIN、MAX、COUNT.. 案例: 1、字符函數 SELECT LENGTH(‘hello‘); # 取字符串長度,結果:5 SELECT CONCAT(‘Hello‘,‘world‘); # 連接字符串,結果:Helloworld SELECT SUBSTR(‘abcdefg‘,3,2); # 截取字符串,結果:cd SELECT REPLACE(‘jack and jue‘,‘j‘,‘bl‘); # 替換字符串,結果:black and blue SELECT INSTR(‘worldworld‘,‘r‘); # 查找子串第一次索引,結果:3 SELECT TRIM(‘*‘ FROM ‘***hello***world***‘); # 去除前後字符串,結果:hello***world SELECT LPAD(‘abc‘,10,‘*‘); # 左填充,結果:*******abc SELECT RPAD(‘abc‘,10,‘*‘); # 右填充,結果:abc******* SELECT UPPER(‘sun‘); # 轉換為大寫,結果:SUN SELECT LOWER(‘FUN‘); # 轉換為小寫,結果:fun 2、數學函數: SELECT ROUND(100.256,2); # 四舍五入,結果:100.26 SELECT CEIL(44.778); # 向上取整,結果:45 SELECT FLOOR(100.2); # 向下取整,結果:100 SELECT ABS(-15); # 取絕對值,結果:15 SELECT POWER(4,2); # m的n次冪,結果:16 SELECT TRUNCATE(100.256,2); # 截斷,結果:100.25 SELECT MOD(10,3); # 取余數,結果:1 SELECT RAND(); # 0-1之間隨機數,結果:0.341342691650002 3、日期函數: SELECT NOW(); # 返回當前系統日期時間 SELECT CURDATE(); # 返回當前系統日期 SELECT CURTIME(); # 返回當前系統時間 SELECT YEAR(NOW()); # 返回當前系統的年 SELECT MONTH(NOW()); # 返回當前系統的月 SELECT DAY(NOW()); # 返回當前系統的日 SELECT HOUR(NOW()); # 返回當前系統的時 SELECT MINUTE(NOW()); # 返回當前系統的分 SELECT SECOND(NOW()); # 返回當前系統的秒 SELECT STR_TO_DATE(‘1980-01-01‘,‘%Y-%c-%d‘); # 將字符轉換成日期 SELECT DATE_FORMAT(NOW(),‘%y年%m月%d日‘); # 將日期轉換成字符 SELECT DATEDIFF(‘2020-01-01‘, NOW()); # 返回兩日期相差天數 4、流程控制函數 SELECT IFNULL(NULL,123); # 如果expr1不是NULL,返回expr1,否則返回expr2 SELECT NULLIF(1,2); # 如果expr1=expr2,返回NULL,否則返回expr1 SELECT IF(1<2,‘yes‘,‘no‘); # 如果expr1是真, 返回expr2, 否則返回expr3 SELECT CASE 1 WHEN 1 THEN ‘one‘ WHEN 2 THEN ‘two‘ ELSE ‘more‘ END; # 枚舉這個字段所有可能的值 SELECT CASE WHEN 1>0 THEN ‘true‘ ELSE ‘false‘ END; # 判斷字段範圍 5、其他函數: SELECT VERSION(); # 返回MySql版本 SELECT DATABASE(); # 返回當前數據庫 SELECT USER(); # 返回當前用戶 SELECT PASSWORD(‘123456‘); # 返回該字符的密碼形式 SELECT MD5(‘123456‘); # 返回該字符的MD5加密形式 SELECT UUID(); # 返回UUID 6、聚合函數 SELECT SUM(salary) FROM employees; # 求和 SELECT AVG(salary) FROM employees; # 求平均值 SELECT MIN(salary) FROM employees; # 求最小值 SELECT MAX(salary) FROM employees; # 求最大值 SELECT COUNT(salary) FROM employees; # 計算個數
分組查詢
語法: SELECT [column,] group function(column), ... FROM table [WHERE condition] [GROUP BY columns] [HAVING condition] [ORDER BY columns (ASC | DESC)]; 案例: 1、簡單分組 案例:查詢每個工種的員工平均工資 SELECT AVG(salary),job_id FROM employees GROUP BY job_id; 2、分組前篩選 案例:查詢郵箱中包含a字符的 每個部門的最高工資 SELECT MAX(salary),department_id FROM employees WHERE email LIKE ‘%a%‘ GROUP BY department_id; 3、分組後篩選 案例:查詢哪個部門的員工個數>5 SELECT COUNT(*),department_id FROM employees GROUP BY department_id HAVING COUNT(*)>5; 4、多個字段分組 案例:查詢每個工種每個部門的最低工資,並按最低工資降序 SELECT MIN(salary),job_id,department_id FROM employees GROUP BY department_id,job_id ORDER BY MIN(salary) DESC;
分頁查詢
語法: SELECT * | { [DISTINCT] column | expression [alias], ... } FROM table [WHERE condition] [GROUP BY columns] [HAVING condition] [ORDER BY columns (ASC | DESC)] [LIMIT { [offset,] row_count | row_count OFFSET offset }]; 註意: offset代表起始索引,默認0 案例: 1、查詢前五條員工信息 SELECT * FROM employees LIMIT 0,5; SELECT * FROM employees LIMIT 5; 2、查詢第11條——第25條 SELECT * FROM employees LIMIT 10,15; SELECT * FROM employees LIMIT 15 OFFSET 10;
連接查詢
語法: SELECT * | { [DISTINCT] column | expression [alias], ... } FROM table [[connect_type] JION table2 ON connect_condition] [WHERE condition] [GROUP BY columns] [HAVING condition] [ORDER BY columns (ASC | DESC)] [LIMIT { [offset,] row_count | row_count OFFSET offset }]; 含義: 又稱多表查詢,當查詢的字段來自於多個表時,就會用到連接查詢 笛卡爾乘積現象: 表1 有m行,表2 有n行,結果=m*n行 發生原因:沒有有效的連接條件 如何避免:添加有效的連接條件 分類: 按年代分類: sql92標準:僅僅支持內連接 sql99標準:支持內連接+外連接(左外和右外)+交叉連接 按功能分類: 內連接:[INNER] JOIN ON 等值連接 非等值連接 自連接 外連接: 左外連接:LEFT [OUTER] JOIN 右外連接:RIGHT [OUTER] JOIN 全外連接:FULL [OUTER] JOIN(MySQL不支持) 交叉連接:CROSS JOIN(笛卡爾集) 說明: 內連接: 特點: 1、內連接結果 = 多表的交集部分 2、n表連接至少需要n-1個連接條件 3、多表的順序沒有要求 4、inner可以省略 5、篩選條件放在where後面,連接條件放在on後面,提高分離性,便於閱讀 6、inner join連接和sql92語法中的等值連接效果是一樣的,都是查詢多表的交集 外連接: 特點: 1、外連接結果 = 內連接結果+主表中有而從表沒有的記錄 2、left join左邊的是主表,right join右邊的是主表,full join兩邊都是主表 3、左外和右外交換兩個表的順序,可以實現同樣的效果 4、一般用於查詢除了交集部分的剩余的不匹配的行 5、全外連接結果 = 內連接的結果+表1中有但表2沒有的+表2中有但表1沒有的 案例: 內連接: 1、等值連接 案例1.查詢員工名、部門名 SQL92語法:SELECT last_name,department_name FROM departments d,employees e WHERE e.`department_id`=d.`department_id`; SQL99語法:SELECT last_name,department_name FROM departments d JOIN employees e ON e.`department_id`=d.`department_id`; 案例2:查詢員工名、部門名和所在的城市 SQL92語法:SELECT last_name,department_name,city FROM employees e,departments d,locations l WHERE e.`department_id`=d.`department_id` AND d.`location_id`=l.`location_id`; SQL99語法:SELECT last_name,department_name,city FROM employees e INNER JOIN departments d ON e.`department_id`=d.`department_id` INNER JOIN locations l ON d.`location_id`=l.`location_id`; 2、非等值連接 案例:查詢員工的工資和工資級別 SQL92語法:SELECT salary,grade_level FROM employees e,job_grades g WHERE e.`salary` BETWEEN g.`lowest_sal`
AND g.`highest_sal`; SQL99語法:SELECT salary,grade_level FROM employees e JOIN job_grades g ON e.`salary` BETWEEN g.`lowest_sal`
AND g.`highest_sal`; 3、自連接 案例:查詢員工名和上級的名稱 SQL92語法:SELECT e.last_name,m.last_name FROM employees e,employees m WHERE e.`manager_id`=m.`employee_id`; SQL99語法:SELECT e.last_name,m.last_name FROM employees e JOIN employees m ON e.`manager_id`=m.`employee_id`; 外連接: 1、左、右外連接 案例:查詢哪個部門沒有員工 左外連接:SELECT d.*, e.employee_id FROM departments d LEFT OUTER JOIN employees e ON d.`department_id`=e.`department_id` WHERE e.`employee_id` IS NULL; 右外連接:SELECT d.*, e.employee_id FROM employees e RIGHT OUTER JOIN departments d ON d.`department_id`=e.`department_id` WHERE e.`employee_id` IS NULL; 2、交叉連接(笛卡爾集) 案例:查詢兩表數據 笛卡爾集:SELECT d.*,e.* FROM departments d,employees e; 交叉連接:SELECT d.*,e.* FROM departments d CROSS JOIN employees e;
子查詢
含義: 嵌套在其他語句內部的select語句稱為子查詢或內查詢 外部語句可以是insert、update、dalete、select等,一般select作為外部語句較多 外部如果為select語句稱為主查詢或外查詢 分類: 按子查詢出現的位置: SELECT後面:支持標量子查詢 FROM後面:支持表子查詢 WHERE或HAVING後面:支持標量子查詢、列子查詢、行子查詢 EXISTS後面:支持標量子查詢、列子查詢、行子查詢、表子查詢 按結果集的行列數不同: 標量子查詢(結果集只有一行一列) 列子查詢(結果集只有一列多行) 行子查詢(結果集有一行多列) 表子查詢(結果集一般為多行多列) 特點: 1、子查詢放在小括號內 2、子查詢一般放在條件的右側 3、標量子查詢,一般搭配著單行操作符使用> < >= <= = <> 4、列子查詢,一般搭配著多行操作符使用 (NOT) IN、ANY|SOME、ALL (NOT) IN:等於列表中的任意一個 ANY|SOME:和子查詢返回的某一個值比較 ALL:和子查詢返回的所有值比較 5、子查詢的執行優先於主查詢執行,主查詢的條件用到了子查詢的結果 案例: 1、標量子查詢 案例1:查詢公司工資最少的員工的last_name,job_id和salary SELECT last_name,job_id,salary FROM employees WHERE salary=( SELECT MIN(salary) FROM employees ); 案例2:查詢job_id與141號員工相同,salary比143號員工多的員工姓名,job_id和工資 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 ); 2、列子查詢 案例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) ); # 或 SELECT last_name FROM employees WHERE department_id =ANY( SELECT DISTINCT department_id FROM departments WHERE location_id IN(1400,1700) ); 案例2:查詢location_id不是1400或1700的部門中的所有員工姓名 SELECT last_name FROM employees WHERE department_id NOT IN( SELECT DISTINCT department_id FROM departments WHERE location_id IN(1400,1700) ); # 或 SELECT last_name FROM employees WHERE department_id <>ALL( SELECT DISTINCT department_id FROM departments WHERE location_id IN(1400,1700) ); 案例3:查詢其它工種中比job_id為‘IT_PROG’工種任一工資低的員工的員工號、姓名、job_id 以及salary SELECT last_name,employee_id,job_id,salary FROM employees WHERE salary<ANY( SELECT DISTINCT salary FROM employees WHERE job_id = ‘IT_PROG‘ ) AND job_id<>‘IT_PROG‘; # 或 SELECT last_name,employee_id,job_id,salary FROM employees WHERE salary<( SELECT MAX(salary) FROM employees WHERE job_id = ‘IT_PROG‘ ) AND job_id<>‘IT_PROG‘; 案例4:查詢其它工種中比job_id為‘IT_PROG’工種所有工資低的員工的員工號、姓名、job_id 以及salary SELECT last_name,employee_id,job_id,salary FROM employees WHERE salary<ALL( SELECT DISTINCT salary FROM employees WHERE job_id = ‘IT_PROG‘ ) AND job_id<>‘IT_PROG‘; # 或 SELECT last_name,employee_id,job_id,salary FROM employees WHERE salary<( SELECT MIN(salary) FROM employees WHERE job_id = ‘IT_PROG‘ ) AND job_id<>‘IT_PROG‘; 3、行子查詢 案例:查詢員工編號最小並且工資最高的員工信息 SELECT * FROM employees WHERE employee_id=( SELECT MIN(employee_id) FROM employees )AND salary=( SELECT MAX(salary) FROM employees); # 或 SELECT * FROM employees WHERE (employee_id,salary)=( SELECT MIN(employee_id),MAX(salary) FROM employees ); 4、表子查詢 案例:查詢有員工的部門名 SELECT department_name FROM departments d WHERE EXISTS( SELECT * FROM employees e WHERE d.`department_id`=e.`department_id` );
聯合查詢
語法: SELECT1 ... UNION [ALL | DISTINCT] SELECT2 ... ... 應用場景: 要查詢的結果來自於多個表,且多個表沒有直接的連接關系,但查詢的信息一致時 特點: 1、要求多條查詢語句的查詢列數是一致的! 2、要求多條查詢語句的查詢的每一列的類型和順序最好一致 3、union關鍵字默認去重,如果使用union all 可以包含重復項 4、多個select語句聯合查詢後的結果字段,都是以第一個select語句的字段為準 案例: 1、查詢部門編號>90或郵箱包含a的員工信息 SELECT * FROM employees WHERE email LIKE ‘%a%‘ OR department_id>90; # 或 SELECT * FROM employees WHERE email LIKE ‘%a%‘ UNION SELECT * FROM employees WHERE department_id>90;
MySQL_基礎_DQL數據查詢語言