03、MySQL常見函式、分組函式、分組查詢
阿新 • • 發佈:2020-07-23
目錄
常見函式
#進階四、函式 /* 函式;類似於Java中的"方法" 為了解決某個問題,將編寫的一系列命令集合封裝在一起,對外僅僅暴露方法名以供外部呼叫 1、自定義方法(函式) 2、呼叫方法(函式) 常見函式: 1、字元函式 2、數學函式 3、日期函式 4、流程控制函式 */ -- 1、字元函式 #concat 拼接 SELECT CONCAT('Hello,', first_name, last_name) AS str FROM employees; #length 獲取位元組長度,由字符集決定 SELECT LENGTH('中國Hello'); #11=6+5 #char_length 獲取字元長度 SELECT CHAR_LENGTH('Hello中國'); #7 #substring 擷取字串 SQL中字串的起始索引從1開始 SELECT SUBSTRING('Hello,MySQL', 7); #MySQL 7代表開始索引 SELECT SUBSTRING('Hello,MySQL', 1, 5); #Hello 1代表起始索引,5代表擷取的個數 #instr 返回字串第一次出現的索引 SELECT INSTR('Hello,Hello', 'llo'); #3 #trim 去除前後空格 SELECT TRIM(' JavaScript '); SELECT TRIM('x' FROM 'xxxxxJavaxxxxx'); #Java # lpad 左填充 SELECT LPAD('Script', 3, 'x'); #為Script左填充x直到3位 #Scr # rpad 右填充 SELECT RPAD('Java', 5, 'b'); #為Java右填充b直到5位 #Javab #查詢員工表中的姓名:姓首字母大寫,其他字母小寫,名所有字母大寫,姓與名之間用_拼接,最後起別名 SELECT CONCAT(UPPER(SUBSTRING(first_name, 1, 1)), LOWER(SUBSTRING(first_name, 2)), '_', UPPER(last_name)) AS finalname FROM employees; # strcmp 比較兩個字串的大小 SELECT STRCMP('ABC', 'AAA'); #1 # left right SELECT LEFT('ShawnYue', 5); #Shawn SELECT RIGHT('ShawnYue', 3); #Yue -- 2、數學函式 #abs 取絕對值 SELECT ABS(-2); #2 #ceil 向上取整 SELECT CEIL(1.2); #2 SELECT CEIL(1.12); #2 #floor 向下取整 SELECT FLOOR(1.78); #1 #round 四捨五入 SELECT ROUND(1.12); #1 SELECT ROUND(1.50); #2 SELECT ROUND(1.87232, 2); #保留小數點後2位 #1.87 # truncate 截斷 SELECT TRUNCATE(1.87121, 2); #1.87 # mod 取餘 SELECT MOD(10, 3); #1 #餘數的正負只與被除數有關 -- 3、日期函式 #now 獲取當前日期時間 SELECT NOW(); #2020-07-22 21:33:38 #curdate 獲取當前日期 SELECT CURDATE(); #2020-07-22 #curtime 獲取當前時間 SELECT CURTIME(); #21:35:06 #datediff 獲取兩個日期的差 SELECT DATEDIFF(CURDATE(), '1998-11-08'); #7928 #date_format 格式化日期 SELECT DATE_FORMAT(CURDATE(), '%Y年%m月%d日'); #2020年07月23日 SELECT DATE_FORMAT(hiredate, '%Y年%m月%d日 %H時%i分%s秒') FROM employees; #str 解析字串 SELECT STR_TO_DATE('2019年7月1日', '%Y年%m月%d日'); #2019-07-01 -- 4、流程控制函式 # if函式 SELECT IF(100 > 90, '大於', '小於'); #大於 SELECT IF(commission_pct IS NOT NULL, salary * 12 * (1 + commission_pct) ,'沒獎金') FROM employees; # case函式 /* CASE 表示式 WHEN 值1 THEN 結果1 WHEN 值2 THEN 結果2 ... ELSE 結果n END */ #部門編號為30,工資顯示為double;部門編號為50,工資顯示為triple;部門編號為60,工資顯示為quadra;否則不變 SELECT department_id, salary, (CASE department_id WHEN 30 THEN salary * 2 WHEN 50 THEN salary * 3 WHEN 60 THEN salary * 4 ELSE salary END) newSalary FROM employees; /* CASE WHEN 條件一 THEN 結果1 WHEN 條件二 THEN 結果2 ... ELSE 結果n END */ #如果工資大於2w,顯示級別為A;大於1.5w,顯示級別為B;大於1w,顯示級別為C;否則顯示D SELECT salary, (CASE WHEN salary > 20000 THEN 'A' WHEN salary > 15000 THEN 'B' WHEN salary > 10000 THEN 'C' ELSE 'D' END) grade FROM employees; #將員工按首字母排序和姓名的長度排序 SELECT last_name, CHAR_LENGTH(last_name) len FROM employees ORDER BY SUBSTRING(last_name, 1, 1) ASC, len ASC;
分組函式
#進階5、分組函式/聚合函式/統計函式 /* 分組函式往往用於將一組資料進行統計計算,最終得到一個值,所以又稱聚合函式/統計函式。 1、常見的分組函式,sum()求和、avg()求平均數、max()求最大值、min()求最小值、count()計算非空欄位值的個數 */ #查詢所有員工的工資和、工資平均值、最高工資、最低工資、有工資的個數 SELECT SUM(salary) 工資和, AVG(salary) 平均工資, MAX(salary) 最大工資, MIN(salary) 最低工資, COUNT(salary) 個數 FROM employees; -- 工資和 平均工資 最大工資 最低工資 個數 -- 691400.00 6461.682243 24000.00 2100.00 107 SELECT MAX(last_name) FROM employees; #Zlotkey #按照字串的字典順序排序 SELECT MIN(last_name) FROM employees; #Abel #查詢員工表中有獎金的人數 SELECT COUNT(commission_pct) FROM employees; #35 #查詢員工表中月薪大於5000的人數 SELECT COUNT(salary) FROM employees WHERE salary > 5000; #58 #查詢有領導的人數 SELECT COUNT(manager_id) FROM employees; #106 #count的補充介紹 /* count計算非空欄位的個數 */ SELECT COUNT(*) FROM employees; #107 統計結果集的行數 #有一列資料不為NULL,就統計,除非某一行所有列都為NULL SELECT COUNT(1) FROM employees; #107 #和count(*)一致 #推薦使用count(*) #搭配distinct使用 #查詢有員工的部門個數 SELECT COUNT(DISTINCT department_id) FROM employees;
分組查詢
#進階六、分組查詢 /* 語法: select 查詢列表 from 表名 where 篩選條件 group by 分組列表; 1、特點:查詢列表往往是分組函式或者分組的欄位; 2、分組查詢分為兩類:(1):分組前篩選where,在group by之前;(2)分組後篩選having,在group by之後 */ #計算每個工種的員工平均工資 SELECT AVG(salary) 平均工資, job_id FROM employees GROUP BY job_id; #查詢每個領導下的員工個數 SELECT manager_id, COUNT(*) 個 FROM employees GROUP BY manager_id; #查詢郵箱中包含a字元的部門的最高工資 SELECT department_id 部門編號, MAX(salary) 最高工資 FROM employees WHERE email LIKE '%a%' AND department_id IS NOT NULL GROUP BY department_id; -- 分組前的篩選:where子句在group by之前執行 #查詢每個領導下有獎金的員工的平均工資 SELECT manager_id 領導編號, TRUNCATE(AVG(salary), 2) 員工平均工資 FROM employees WHERE commission_pct IS NOT NULL GROUP BY manager_id; -- 分組後的篩選:having子句在group by之後執行 #查詢哪個部門的員工個數大於5 /* 錯誤版: select department_id 部門, COUNT(*) 員工個數 from employees where COUNT(*) > 5 group by department_id; */ # where後面不能使用分組函式 SELECT department_id 部門, COUNT(*) 員工個數 FROM employees GROUP BY department_id HAVING COUNT(*) > 5; # having後面可以使用分組函式 #每個工種有獎金的員工的最高工資>12000的工種編號和最高工資 SELECT job_id 工種編號, MAX(salary) 最高工資 FROM employees WHERE commission_pct IS NOT NULL GROUP BY job_id HAVING MAX(salary) > 12000; #領導編號>102的每個領導手下員工的最低工資大於5000的最低工資 SELECT manager_id 領導編號, MIN(salary) 最低工資 FROM employees WHERE manager_id > 102 GROUP BY manager_id HAVING MIN(salary) > 5000; #每個工種有獎金的員工的最高工資>6000的工種編號和最高工資,並按最高工資降序 SELECT job_id 工種編號, MAX(salary) 最高工資 FROM employees WHERE commission_pct IS NOT NULL GROUP BY job_id HAVING MAX(salary) > 6000 ORDER BY 最高工資 DESC; -- 按多個欄位分組 #查詢每個工種每個部門的最低工資,並按最低工資降序 SELECT MIN(salary) 最低工資, job_id 工種編號, department_id 部門編號 FROM employees GROUP BY job_id, department_id ORDER BY 最低工資 DESC; #工種一樣,部門一樣的才算做一組員工 /* 執行順序: 1、from子句 2、where子句 3、group by子句 4、having子句 5、select子句 6、order by子句 */