SQL / 資料查詢語言DQL(Data Query Language )
阿新 • • 發佈:2021-07-26
1、基礎查詢
#進階1:基礎查詢 /* 語法: select 查詢列表 from 表名; 1、查詢列表可以是:表中的欄位、常量值、表示式、函式 2、查詢的結果是一個虛擬的表格 ( 不儲存 ) */ #開啟資料庫 USE myemployees; #1、查詢表中的單個欄位 SELECT last_name FROM employees; #2、查詢表中的多個欄位 SELECT last_name,salary,email FROM employees; #3、查詢表中的所有欄位 #方式一( 欄位,雙擊欄位可以快速新增,選中程式碼,按F12格式化或按F9執行 ): SELECT `first_name`, # 欄位兩邊的著重號`是區分是關鍵字還是欄位的,可以去掉, `last_name`, `email`, `phone_number`, `job_id`, `salary`, `commission_pct`, `manager_id`, `department_id`, `hiredate`View CodeFROM employees ; # 方式二,* 代表所有欄位,欄位與原始表一樣: SELECT * FROM employees; #4、查詢常量值 SELECT 100; SELECT 'john'; #查詢字元常量 #5、查詢表示式 SELECT 100*98; #6、查詢函式 SELECT VERSION(); #查詢函式VERSION()的返回值 #7、起別名 /* 便於理解(提高可讀性) 如果要查詢的欄位有重名的使用別名可以區分開來 */ #方式一:使用as SELECT 100%98 AS 結果; SELECT last_name AS 姓, first_name AS 名 FROMemployees; #方式二:使用空格 SELECT last_name 姓, first_name 名 FROM employees; #別名含有特殊符號的要加雙引號或單引號 SELECT salary AS "out put" FROM employees; #8、去重 #查詢員工表中涉及的所有的部門編號 ( 去掉重複的編號用distinct ) SELECT DISTINCT department_id FROM employees; #9、+號的作用 /* java中的+號: 運算子,兩個運算元都為數值型 連線符,只要一個運算元為字串 mysql中的+號: 運算子,僅僅只有一個功能 select 100+90; #兩個運算元都為數值型,則做加法運算 select '123'+90; #只要其中一個運算元為字元型,試圖把字元型轉為數值型, #轉換成功則繼續做加法運算 select 'john'+90; #轉換失敗則字元型數值為0,再做加法運算 select null+90; #只要其中一個運算元為null,結果為null*/ #查詢員工名和姓連線成一個欄位並顯示為姓名,使用字元連線函式concat(), #只要其中一個運算元為null,結果為null SELECT CONCAT(last_name, ' ', first_name) AS 姓名 FROM employees ; #使用ifnull()函式,避免結果為null SELECT IFNULL(`commission_pct`, 0) AS 獎金率, `commission_pct` FROM employees ; SELECT CONCAT( `first_name`, ',', `last_name`, ',', `email`, ',', IFNULL(`commission_pct`, 0) ) AS out_put FROM employees ;
2、條件查詢
#進階2:條件查詢 /* 語法:( 執行順序 from/where/select ) select 查詢列表 from 表名 where 篩選條件(結果是true或false); 分類: 一、按條件表示式篩選 條件運算子: > < = != <> >= <= <=> 其中 <> 與 != 相同,<=> 安全等於 二、按邏輯表示式篩選 ( 作用:是連線條件表示式的 ) 邏輯運算子: && || ! and or not 三、模糊查詢 like between and in is null|is not null */ USE myemployees; #一、按條件表示式篩選 #查詢工資>12000的員工的資訊 SELECT * FROM employees WHERE salary > 12000 ; #查詢部門編號不等於90號的員工名和部門編號 SELECT first_name, department_id FROM employees WHERE department_id <> 90 ; #二、按邏輯表示式篩選 #查詢工資在10000到20000之間的員工名、工資及獎金 SELECT first_name, salary, commission_pct FROM employees WHERE salary >= 10000 AND salary <= 20000 ; #查詢部門編號不是在90到110之間 或 工資高於15000的員工資訊 /* select * from employees where department_id <90 or department_id > 110 or salary > 15000 ; */ SELECT * FROM employees WHERE NOT ( department_id >= 90 AND department_id <= 110 ) OR salary > 15000 ; #模糊查詢 /* like 一般和萬用字元搭配使用 萬用字元: %任意多個字元包含0個字元 _任意單個字元 between and in is null|is not null */ #查詢員工中包含字元a的員工資訊 SELECT * FROM employees WHERE first_name LIKE '%a%' ; #查詢員工中第三個字元為e,第五個字元為a的員工和工資 SELECT first_name, salary FROM employees WHERE first_name LIKE '__e_a%' ; #查詢員工姓名中第二個字元為_的員工姓名 /*select last_name from employees where last_name like '_\_%' ; #使用轉義字元\ */ SELECT last_name FROM employees WHERE last_name LIKE '_$_%' ESCAPE '$' ; # ESCAPE 定義轉義字元 #查詢員工編號在100到120之間的員工資訊 SELECT * FROM employees WHERE employee_id >= 100 AND employee_id <= 120 ; #查詢員工部門號第一個數字為1的員工資訊,like 可以查詢數值型的欄位 SELECT * FROM employees WHERE department_id LIKE '1__' ; #between and 提高語句簡潔度,包含臨界值如下的100 120,兩個臨界值不調換順序 SELECT * FROM employees WHERE employee_id BETWEEN 100 AND 120 ; #查詢員工的工種編號是 IT_PROG、AD_VP、AD_PRES中的一個員工名和工種編號 SELECT first_name, job_id FROM employees WHERE job_id = 'IT_PROT' OR job_id = 'AD_VP' OR job_id = 'AD_PRES' ; #IN 判斷某個欄位的值是否屬於in列表中的某一項 #比使用or提高語句簡潔度,in類別的值型別必須一致或相容,不支援萬用字元 SELECT first_name, job_id FROM employees WHERE job_id IN ('IT_PROT', 'AD_VP', 'AD_PRES') ; #查詢沒有獎金的員工名和獎金率 /* = 或 <> 不能判斷 null is null或is not null 可以判斷null值 */ SELECT first_name, commission_pct FROM employees WHERE commission_pct IS NULL ; # 沒有獎金 WHERE commission_pct IS NOT NULL ; #安全等於 <=> ,可讀性不好 SELECT first_name, commission_pct FROM employees WHERE commission_pct <=> NULL ; #is null #獎金等於12000的員工名 SELECT first_name, salary FROM employees WHERE salary <=> 12000 ; # is null 僅僅可以判斷null值,可讀性高,建議使用 # <=> 即可以判斷null值,又可以判斷普通的數值,可讀性較低 #查詢員工號為176的員工的姓名和部門和年薪 SELECT first_name, department_id, salary * 12 *(1+ IFNULL(commission_pct, 0)) AS 年薪 FROM employees WHERE employee_id = 176 ; #查詢沒有獎金,且工資小於18000的salary,last_name SELECT last_name, salary FROM employees WHERE commission_pct IS NULL AND salary < 18000 ; #查詢 employee 表中,job_id 不為 'IT' 或者 工資為12000的員工的資訊 SELECT * FROM employees WHERE job_id <> 'IT' OR salary = 12000 ; #檢視部門 departments 表的結構 DESC departments; #檢視部門departments表中涉及到了哪些位置編號 SELECT DISTINCT #distinct 去重 location_id FROM departments ; #------------------------ SELECT * FROM employees ; #如果判斷的欄位有null值下面語句與上面語句不一樣 SELECT * FROM employees WHERE commission_pct LIKE '%%' AND last_name LIKE '%%' ;View Code
3、排序查詢
#進階3:排序查詢 /* 語法: select 查詢列表 from 表 【where 篩選條件】 order by 排序列表 【asc|desc】 特點: 1、asc是升序,desc是降序 如果不寫,預設是升序 2、order by 子句中可以支援單個欄位、多個欄位、表示式、函式、別名 3、order by 子句一般放在查詢語句的最後面,limit子句除外 */ #查詢員工資訊,要求工資從高到低排序 SELECT * FROM employees ORDER BY salary DESC ; #查詢部門編號 >= 90的員工資訊,按入職時間的先後進行排序 【 新增篩選條件 】 SELECT * FROM employees WHERE department_id >= 90 ORDER BY hiredate ; #按年薪的高低顯示員工的資訊和年薪【 按表示式排序 】 SELECT *, salary * 12 * (1 + IFNULL(commission_pct, 0)) AS 年薪 FROM employees ORDER BY salary * 12 * (1 + IFNULL(commission_pct, 0)) DESC; #按年薪的高低顯示員工的資訊和年薪【 按別名排序 】 SELECT *, salary * 12 * (1 + IFNULL(commission_pct, 0)) AS 年薪 FROM employees ORDER BY 年薪 DESC; #按姓名的長度顯示員工的姓名和工資【按函式排序】 SELECT LENGTH(last_name) AS 位元組長度, last_name, salary FROM employees ORDER BY LENGTH(last_name) DESC ; #查詢員工資訊,要求先按工資升序排序,再按員工編號降序排序【按多個欄位排序】 SELECT * FROM employees ORDER BY salary ASC, employee_id DESC ; #查詢員工的姓名和部門號和年薪,按年薪降序 按姓名升序 SELECT last_name, department_id, salary * 12 * (1 + IFNULL(commission_pct, 0)) AS 年薪 FROM employees ORDER BY 年薪 DESC, last_name ASC ; #選擇工資不在8000到17000的員工的姓名和工資,按工資降序 SELECT last_name, salary FROM employees WHERE salary NOT BETWEEN 8000 AND 17000 ORDER BY salary ASC ; #查詢郵箱中包含e的員工資訊,並先按郵箱的位元組數降序,再按部門號升序 SELECT * FROM employees WHERE email LIKE '%e%' ORDER BY LENGTH(email) DESC, department_id ASC ;View Code
4、函式查詢
#進階4:常見函式 /* 概念:類似於Java的方法,將一組邏輯語句封裝在方法體中,對外暴露方法名 好處:1、隱藏了實現細節 2、提高程式碼的重用性 呼叫:select 函式名(實參列表) 【from 表】; 特點:叫什麼(函式)、幹什麼(函式功能) 分類: 1、單行函式,如concat、length、ifnull等 字元函式、數學函式、日期函式、其他函式、流程控制函式 2、分組函式 功能:做統計使用,又稱為統計函式、聚合函式、組函式 常見函式: 一、單行函式 字元函式: length concat substr instr trim upper lower lpad rpad replace 數學函式: round ceil floor truncate mod 日期函式: now curdate curtime year month monthname day hour minute sencond str_to_date date_format 其他函式: version database user 控制函式: if case 二、分組函式 */ #單行函式 #一、字元函式 #length 獲取引數值的位元組個數 SELECT LENGTH('john'); SELECT LENGTH('張三丰hahaha'); #一個漢字3個位元組,結果為15 SHOW VARIABLES LIKE '%char%'; #utf8 #concat 拼接字串 SELECT CONCAT(last_name,'_',first_name) 姓名 FROM employees; #upper、lower SELECT UPPER('john'); SELECT LOWER('JOHN'); #將姓變大寫,名變小寫,然後拼接 SELECT CONCAT(LOWER(first_name),'_',UPPER(last_name)) 姓名 FROM employees; #substr substring 擷取字元 索引從1開始 SELECT SUBSTR('李莫愁愛上了陸展元',7) out_put; SELECT SUBSTR('李莫愁愛上了陸展元',1,3) out_put; #1是開始索引,3是字元長度 SELECT SUBSTR('limochouaishangleluzhanyuan',7); #姓名中首字元大寫,其他字元小寫然後用_拼接,顯示出來 SELECT CONCAT(UPPER(SUBSTR(last_name,1,1)),'_',SUBSTR(last_name,2)) AS 姓名 FROM employees; #instr 返回子串第一次出現的索引,如果找不到,返回0 SELECT INSTR('楊不悔','不悔'); #返回值,是首次適配的索引值 #trim 去除首尾字元 SELECT LENGTH(TRIM(' 張翠山 ')) AS out_put; SELECT TRIM('a' FROM 'aaaaa張aa翠山aaaa') AS out_put; #lpad 左填充 不夠長度從左邊填充字元 長度低於字元個數會截斷字串 SELECT LPAD('殷素素',10,'*') AS out_put; #rpad 右填充 SELECT RPAD('殷素素',10,'*') AS out_put; #replace 替換 SELECT REPLACE('Hello World Hello','Hello','tt') AS out_put; #二、數學函式 #round 四捨五入 SELECT ROUND(1.657); SELECT ROUND(1.657,2); #保留小數點後2位 #ceil 向上取整,返回 >= 該引數的最小整數 SELECT CEIL(1.003); #floor 向下取整,返回 <= 該引數的最小整數 SELECT FLOOR(9.99); # 9 SELECT FLOOR(-9.99); # -10 #truncate 截斷 SELECT TRUNCATE(1.6999,1); # 1.6 #mod 取餘 a-a/b*b SELECT MOD(10,3); # 1 SELECT -10%3; #三、日期函式 #now 返回當前系統日期+時間 SELECT NOW(); #curdate 返回當前系統日期,不包含時間 SELECT CURDATE(); #curtime 返回當前系統時間,不包含日期 SELECT CURTIME(); #------------------------ SELECT CURDATE(),CURTIME(); #可以獲取指定的部分,年,月,日,小時,分鐘,秒 SELECT YEAR(NOW()); SELECT YEAR('1998-1-1'); SELECT YEAR('1998/1/1'); SELECT YEAR('1998.1.1'); SELECT YEAR(hiredate) AS 年 FROM employees; SELECT MONTH(NOW()); SELECT MONTH('1998.1.1'); SELECT MONTHNAME(NOW()); #顯示英文月名 monthname SELECT DAY(NOW()); #day SELECT MINUTE(NOW()); # minute SELECT HOUR(NOW()); SELECT SECOND(NOW()); #str_to_date 將日期格式的字元轉換成指定格式的日期,解析失敗返回 null #%Y四位年份 %y二位年份 %m補0的月份 %c月份 %d日 %H 24小時制 %h 12小時制 %i分鐘 %s秒 SELECT STR_TO_DATE('7.22.2021','%m.%d.%Y'); #前後格式一致、正確 #date_format: 將日期轉換成字元 轉換失敗返回 null SELECT DATE_FORMAT('2021.7.22','%Y年%m月%d日'); #查詢入職日期為1992-4-3的員工資訊 SELECT * FROM employees WHERE hiredate = '1992-4-3'; SELECT * FROM employees WHERE hiredate = STR_TO_DATE('4-3 1992','%c-%d %Y'); #查詢有獎金的員工名和入職日期(XX月/XX日 XX年) SELECT last_name, DATE_FORMAT(hiredate,'%m月/%d日 %y年') AS 入職日期 FROM employees WHERE commission_pct IS NOT NULL; #四、其他函式 SELECT VERSION(); SELECT DATABASE(); #檢視當前庫 SELECT USER(); #五、流程控制函式 #if函式: if else 的效果 SELECT IF(10 > 5,'大','小'); SELECT last_name, commission_pct, IF( commission_pct IS NULL, '沒獎金,哈哈', '有獎金,嘻嘻' ) AS 備註 FROM employees ; #case函式 方式一:switch case的效果 /* Java中: switch(變數或表示式){ case 常量1:語句1;break; ... default: 語句n; break; } mysql中 case 要判斷的欄位或表示式 #case相當於Java的switch when 常量1 then 要顯示的值1或語句1 #when相當於Java的case ... else 要顯示的值n或語句n #相當於Java的default end #結束標誌 */ /*查詢員工的工資,要求 部門號=30,顯示的工資為1.1倍 部門號=40,顯示的工資為1.2倍 部門號=50,顯示的工資為1.3倍 其他部門,顯示的工資為原工資 */ SELECT salary AS 原始工資, department_id, CASE department_id WHEN 30 THEN salary * 1.1 #值不是語句 WHEN 40 THEN salary * 1.2 WHEN 50 THEN salary *1.3 ELSE salary END AS 新工資 FROM employees; #case函式 方式二:類似於 多重if /* Java中: if(條件1){ 語句1: }else if(條件2){ 語句2: } ... else{ 語句n: } sql中: case when 條件1 then 要顯示的值1或語句1 ... else 要顯示的值n或語句n end */ /*查詢員工的工資情況 如果工資 > 20000,顯示A級別 如果工資 >15000,顯示B級別 如果工資 >10000,顯示C級別 否則,顯示D級別 */ SELECT salary, # 顯示salay,後面還有顯示加逗號 CASE WHEN salary > 20000 THEN 'A' # 值1 'A' WHEN salary > 15000 THEN 'B' WHEN salary > 10000 THEN 'C' ELSE 'D' END AS 工資級別 # 顯示 工資級別 FROM employees; #顯示系統時間(注:日期+時間) SELECT NOW(); #查詢員工號,姓名,工資,以及工資提高百分之20後的結果(new salary) SELECT employee_id, last_name, salary,salary * 1.20 AS 'new salary' FROM employees; #將員工的姓名按首字母排序,並寫出姓名的長度(length) SELECT LENGTH(last_name) AS 'LENGTH', SUBSTR(last_name,1,1) AS 首字元, last_name FROM employees ORDER BY 首字元 ASC; #做一個查詢,產生下面結果 Dream Salary King earns 24000 monthly but wants 72000 #用到拼接 concat SELECT CONCAT( last_name, ' earns ', salary, ' monthly but wants ', salary * 3 ) AS 'Dream Salary' FROM employees WHERE salary = 24000 ; #使用case-when 方式一: SELECT last_name, job_id AS job, CASE job_id WHEN 'AD_PRES' THEN 'A' WHEN 'ST_MAN' THEN 'B' WHEN 'IT_PROG' THEN 'C' WHEN 'SA_PRE' THEN 'D' WHEN 'ST_CLEAK' THEN 'E' END AS grade FROM employees WHERE job_id = 'AD_PRES'; #分組函式 /* 功能:用作統計使用,又稱為聚合函式或統計函式或組函式 分類: sum 求和、 avg 平均值、max 最大值、min 最小值、count 計算個數(非空值) 特點: 1、sum、avg一般用於處理數值型 max、min、count可以處理任何型別 2、以上分組函式都忽略null值 3、可以和distinct搭配實現去重的運算 4、count 詳細介紹 一般使用 COUNT(*) 用於統計行數 5、和分組函式一同查詢的欄位要求是group by 後的欄位 */ #簡單的使用 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 SUM(salary) AS 和, AVG(salary) AS 平均, MAX(salary) AS 最高, MIN(salary) AS 最低, COUNT(salary) 個數 FROM employees ; SELECT SUM(salary) AS 和, ROUND(AVG(salary),2) AS 平均, MAX(salary) AS 最高, MIN(salary) AS 最低, COUNT(salary) 個數 FROM employees ; #和 distinct 搭配 SELECT COUNT(DISTINCT salary) FROM employees; # distinct與引數之間是空格 # count函式的詳細介紹,支援4種過載 SELECT COUNT(salary) FROM employees; SELECT COUNT(*) FROM employees; #統計總行數 用的最多 SELECT COUNT(1) FROM employees; #在表中加了 一列 的常量值( 1,2 或 '崔俠'等等常量 ) 並統計行總行數 #效率: # myisam 儲存引擎下 count(*)的效率最高 # innodb 儲存引擎下 COUNT(*) 和 count(1)的效率差不多, 比 count(欄位)要高一些 #和分組函式一同查詢的欄位有限制 #和分組函式一同查詢的欄位:要求是group by 後的欄位 #查詢公司員工工資的最大值,最小值,平均值,總和 SELECT MAX(salary),MIN(salary),AVG(salary),SUM(salary) FROM employees; #查詢員工表中的最大入職時間和最小入職時間的長差天數 ( diffrence ) SELECT DATEDIFF( # datediff函式 計算2個日期之間的天數 MAX(DISTINCT hiredate), MIN(DISTINCT hiredate) ) AS 'diffrence' FROM employees ; #------------------------------- SELECT DATEDIFF(NOW(),'1995.1.1'); #查詢部門編號為90的員工個數 SELECT COUNT(*) FROM employees WHERE department_id = 90;View Code
5、分組查詢