2019獨角獸企業重金招聘Python工程師標準>>>
查詢數據指從數據庫中獲取所需要的數據。查詢數據是數據庫操作中最常用,也是最重要的操作。用戶可以根據自己對數據的需求,使用不同的查詢方式。通過不同的查詢方式,可以獲得不同的數據。MySQL中是使用SELECT語句來查詢數據的。在這一章中將講解的內容包括。
1、查詢語句的基本語法
2、在單表上查詢數據
3、使用聚合函數查詢數據
4、多表上聯合查詢
5、子查詢
6、合并查詢結果
7、為表和字段取別名
8、使用正則表達式查詢
什么是查詢?
怎么查的?
數據的準備如下:
- create?table?STUDENT(??
- STU_ID?int?primary?KEY,??
- STU_NAME?char(10)?not?null,??
- STU_AGE?smallint?unsigned??not?null,??
- STU_SEX?char(2)?not?null??
- );??
- insert??into?STUDENT?values(2001,'小王',13,'男');??
- insert??into?STUDENT?values(2002,'明明',12,'男');??
- insert??into?STUDENT?values(2003,'紅紅',14,'女');??
- insert??into?STUDENT?values(2004,'小花',13,'女');??
- insert??into?STUDENT?values(2005,'天兒',15,'男');??
- insert??into?STUDENT?values(2006,'阿獵',13,'女');??
- insert??into?STUDENT?values(2007,'阿貓',16,'男');??
- insert??into?STUDENT?values(2008,'阿狗',17,'男');??
- insert??into?STUDENT?values(2009,'黑子',14,'男');??
- insert??into?STUDENT?values(2010,'小玉',13,'女');??
- insert??into?STUDENT?values(2011,'頭頭',13,'女');??
- insert??into?STUDENT?values(2012,'冰冰',14,'女');??
- insert??into?STUDENT?values(2013,'美麗',13,'女');??
- insert??into?STUDENT?values(2014,'神樂',12,'男');??
- insert??into?STUDENT?values(2015,'天五',13,'男');??
- insert??into?STUDENT?values(2016,'小三',11,'男');??
- insert??into?STUDENT?values(2017,'阿張',13,'男');??
- insert??into?STUDENT?values(2018,'阿杰',13,'男');??
- insert??into?STUDENT?values(2019,'阿寶',13,'女');??
- insert??into?STUDENT?values(2020,'大王',14,'男');??
然后這是學生成績表,其中定義了外鍵約束
- create?table?GRADE(??
- STU_ID?INT?NOT?NULL,??
- STU_SCORE?INT,??
- foreign?key(STU_ID)?references?STUDENT(STU_ID)??
- );??
- insert??into?GRADE?values(2001,90);??
- insert??into?GRADE?values(2002,89);??
- insert??into?GRADE?values(2003,67);??
- insert??into?GRADE?values(2004,78);??
- insert??into?GRADE?values(2005,89);??
- insert??into?GRADE?values(2006,78);??
- insert??into?GRADE?values(2007,99);??
- insert??into?GRADE?values(2008,87);??
- insert??into?GRADE?values(2009,70);??
- insert??into?GRADE?values(2010,71);??
- insert??into?GRADE?values(2011,56);??
- insert??into?GRADE?values(2012,85);??
- insert??into?GRADE?values(2013,65);??
- insert??into?GRADE?values(2014,66);??
- insert??into?GRADE?values(2015,77);??
- insert??into?GRADE?values(2016,79);??
- insert??into?GRADE?values(2017,82);??
- insert??into?GRADE?values(2018,88);??
- insert??into?GRADE?values(2019,NULL);??
- insert??into?GRADE?values(2020,NULL);??
一、查詢語句的基本語法
查詢數據是指從數據庫中的數據表或視圖中獲取所需要的數據,在MySQL中,可以使用SELECT語句來查詢數據。根據查詢條件的不同,數據庫系統會找到不同的數據。
SELECT語句的基本語法格式如下:
- SELECT?屬性列表??
- ???????FROM?表名或視圖列表??
- ???????[WHERE?條件表達式1]??
- ???????[GROUP?BY?屬性名1?[HAVING?條件表達式2]]??
- ???????[ORDER?BY?屬性名2?[ASC|DESC]]??
- 屬性列表:表示需要查詢的字段名。
- 表名或視圖列表:表示即將進行數據查詢的數據表或者視圖,表或視圖可以有多個。
- 條件表達式1:設置查詢的條件。
- 屬性名1:表示按該字段中的數據進行分組。
- 條件表達式2:表示滿足該表達式的數據才能輸出。
- 屬性2:表示按該字段中的數據進行排序,排序方式由ASC或DESC參數指定。
- ASC:表示按升序的順序進行排序。即表示值按照從小到大的順序排列。這是默認參數。
- DESC:表示按降序的順序進行排序。即表示值按照從大到小的順序排列。
如果有WHERE子句,就按照“條件表達式1”指定的條件進行查詢;如果沒有WHERE子句,就查詢所有記錄。
如果有GROUP BY子句,就按照“屬性名1”指定的字段進行分組;如果GROUP BY子句后面帶著HAVING關鍵字,那么只有滿足“條件表達式2”中指定的條件的記錄才能夠輸出。GROUP BY子句通常和COUNT()、SUM()等聚合函數一起使用。
如果有ORDER BY子句,就按照“屬性名2”指定的字段進行排序。排序方式由ASC或DESC參數指定。默認的排序方式為ASC。
二、在單表上查詢數據
2.1、查詢所有字段
- select?*?from?STUDENT;??
??
2.2、按條件查詢
- select?*?from?STUDENT?where?STU_AGE>13;??

IN關鍵字可以判斷某個字段的值是否在指定的集合中。如果字段的值在集合中,則滿足查詢條件,該紀錄將被查詢出來。如果不在集合中,則不滿足查詢條件。其語法規則如下:[ NOT ] IN ( 元素1, 元素2, …, 元素n )?
- select?*?from?STUDENT?where?STU_AGE?in(11,12);??

BETWEEN AND關鍵字可以判讀某個字段的值是否在指定的范圍內。如果字段的值在指定范圍內,則滿足查詢條件,該紀錄將被查詢出來。如果不在指定范圍內,則不滿足查詢條件。其語法規則如下:
[ NOT ] BETWEEN 取值1 AND 取值2?
- select?*?from?STUDENT?where?STU_AGE?between?13?and?15;??

- select?*?from?STUDENT?where?STU_AGE?NOT?IN(13,14,16);??
OR關鍵字也可以用來聯合多個條件進行查詢,但是與AND關鍵字不同。使用OR關鍵字時,只要滿足這幾個查詢條件的其中一個,這樣的記錄將會被查詢出來。如果不滿足這些查詢條件中的任何一個,這樣的記錄將被排除掉。OR關鍵字的語法規則如下:
條件表達式1 OR 條件表達式2 [ …OR 條件表達式n ]
其中,OR可以用來連接兩個條件表達式。而且,可以同時使用多個OR關鍵字,這樣可以連接更多的條件表達式。
- select?*?from?STUDENT?where?STU_ID<2005?OR?STU_ID>2015;??

AND關鍵字可以用來聯合多個條件進行查詢。使用AND關鍵字時,只有同時滿足所有查詢條件的記錄會被查詢出來。如果不滿足這些查詢條件的其中一個,這樣的記錄將被排除掉。AND關鍵字的語法規則如下:
條件表達式1 AND 條件表達式2 [ … AND 條件表達式n ]
其中,AND可以連接兩個條件表達式。而且,可以同時使用多個AND關鍵字,這樣可以連接更多的條件表達式。
LIKE關鍵字可以匹配字符串是否相等。如果字段的值與指定的字符串相匹配,則滿足查詢條件,該紀錄將被查詢出來。如果與指定的字符串不匹配,則不滿足查詢條件。其語法規則如下:[ NOT ] LIKE '字符串'?
“NOT”可選參數,加上 NOT表示與指定的字符串不匹配時滿足條件;“字符串”表示指定用來匹配的字符串,該字符串必須加單引號或雙引號。
- select?*?from?STUDENT?where?STU_NAME?LIKE?'%王';??

- select?*?from?STUDENT?where?STU_NAME?LIKE?'阿%';??

- insert??into?STUDENT?values(2021,'天下無鏡',14,'男');??
然后
- select?*?from?STUDENT?where?STU_NAME?LIKE?'_下_';??
但是如果下后面加兩個_符號?
- select?*?from?STUDENT?where?STU_NAME?LIKE?'_下__';??

“字符串”參數的值可以是一個完整的字符串,也可以是包含百分號(%)或者下劃線(_)的通配字符。二者有很大區別
“%”可以代表任意長度的字符串,長度可以為0;
“_”只能表示單個字符。
如果要匹配姓張且名字只有兩個字的人的記錄,“張”字后面必須要有兩個“_”符號。因為一個漢字是兩個字符,而一個“_”符號只能代表一個字符。
(4)空值查詢
IS NULL關鍵字可以用來判斷字段的值是否為空值(NULL)。如果字段的值是空值,則滿足查詢條件,該記錄將被查詢出來。如果字段的值不是空值,則不滿足查詢條件。其語法規則如下:
IS [ NOT ] NULL
其中,“NOT”是可選參數,加上NOT表示字段不是空值時滿足條件。
IS NULL是一個整體,不能將IS換成”=”.
三、使用聚合函數查詢數據
3.1、group by 分組
如下:
- select?*?from?STUDENT?group?by?STU_SEX;??
如果想看分組的內容,可以加groub_concat?
- select?STU_SEX,group_concat(STU_NAME)?from?STUDENT?group?by?STU_SEX;??

3.2、一般情況下group需與統計函數(聚合函數)一起使用才有意義
?先準備一些數據:
- create?table?EMPLOYEES(??
- EMP_NAME?CHAR(10)?NOT?NULL,??
- EMP_SALARY?INT?unsigned?NOT?NULL,??
- EMP_DEP?CHAR(10)?NOT?NULL??
- );??
- insert?into?EMPLOYEES?values('小王',5000,'銷售部');??
- insert?into?EMPLOYEES?values('阿小王',6000,'銷售部');??
- insert?into?EMPLOYEES?values('工是不',7000,'銷售部');??
- insert?into?EMPLOYEES?values('人人樂',3000,'資源部');??
- insert?into?EMPLOYEES?values('滿頭大',4000,'資源部');??
- insert?into?EMPLOYEES?values('天生一家',5500,'資源部');??
- insert?into?EMPLOYEES?values('小花',14500,'資源部');??
- insert?into?EMPLOYEES?values('大玉',15000,'研發部');??
- insert?into?EMPLOYEES?values('條條',12000,'研發部');??
- insert?into?EMPLOYEES?values('笨笨',13000,'研發部');??
- insert?into?EMPLOYEES?values('我是天才',15000,'研發部');??
- insert?into?EMPLOYEES?values('無語了',6000,'審計部');??
- insert?into?EMPLOYEES?values('什么人',5000,'審計部');??
- insert?into?EMPLOYEES?values('不知道',4000,'審計部');??
mysql中的五種統計函數:
(1)max:求最大值
求每個部門的最高工資:
- select?EMP_NAME,EMP_DEP,max(EMP_SALARY)?from?EMPLOYEES?group?by?EMP_DEP;??

(2)min:求最小值
求每個部門的最仰工資:
- select?EMP_NAME,EMP_DEP,min(EMP_SALARY)?from?EMPLOYEES?group?by?EMP_DEP;??

?(3)sum:求總數和
求每個部門的工資總和:
- select?EMP_DEP,sum(EMP_SALARY)?from?EMPLOYEES?group?by?EMP_DEP??

(4)avg:求平均值
求每個部門的工資平均值
- select?EMP_DEP,avg(EMP_SALARY)?from?EMPLOYEES?group?by?EMP_DEP;??

(5)count:求總行數
求每個部門工資大于一定金額的人數
- select?EMP_DEP,count(*)?from?EMPLOYEES?where?EMP_SALARY>=500?group?by?EMP_DEP;??

3.3、帶條件的groub by 字段 having,利用HAVING語句過濾分組數據
having 子句的作用是篩選滿足條件的組,即在分組之后過濾數據,條件中經常包含聚組函數,使用having 條件顯示特定的組,也可以使用多個分組標準進行分組。
having 子句被限制子已經在SELECT語句中定義的列和聚合表達式上。通常,你需要通過在HAVING子句中重復聚合函數表達式來引用聚合值,就如你在SELECT語句中做的那樣。
- select?EMP_DEP,avg(EMP_SALARY),group_concat(EMP_NAME)from?EMPLOYEES??group?by?EMP_DEP?HAVING??avg(EMP_SALARY)?>=6000;??
四、多表上聯合查詢
多表上聯合查詢分為內連接查詢和外連接查詢
(1)隱式內連接查詢
- select?STUDENT.STU_ID,STUDENT.STU_NAME,STUDENT.STU_AGE,STUDENT.STU_SEX,GRADE.STU_SCORE?from?STUDENT,GRADE?WHERE?STUDENT.STU_ID=GRADE.STU_ID?AND?GRADE.STU_SCORE?>=90;??
(2)顯式內連接查詢
- select?STUDENT.STU_ID,STUDENT.STU_NAME,STUDENT.STU_AGE,STUDENT.STU_SEX,GRADE.STU_SCORE?from?STUDENT?inner?join?GRADE?on?STUDENT.STU_ID=GRADE.STU_ID?AND?GRADE.STU_SCORE?>=90;??
用法:select .... from 表1 inner join 表2 on 條件表達式
(3)外連接查詢
left join.左連接查詢。
用法 :select .... from 表1 left join 表2 on 條件表達式
意思是表1查出來的數據不能為null,但是其對應表2的數據可以為null
- select?STUDENT.STU_ID,STUDENT.STU_NAME,STUDENT.STU_AGE,STUDENT.STU_SEX,GRADE.STU_SCORE?from?STUDENT?left?join?GRADE?on?STUDENT.STU_ID=GRADE.STU_ID;??

right join就是相反的了,用法相同
用left join的時候,left join操作符左側表里的信息都會被查詢出來,右側表里沒有的記錄會填空(NULL).right join亦然;inner join的時候則只有條件合適的才會顯示出來
full join()
完整外部聯接返回左表和右表中的所有行。當某行在另一個表中沒有匹配行時,則另一個表的選擇列表列包含空值。如果表之間有匹配行,則整個結果集行包含基表的數據
值。
????? 僅當至少有一個同屬于兩表的行符合聯接條件時,內聯接才返回行。內聯接消除與另一個表中的任何行不匹配的行。而外聯接會返回 FROM 子句中提到的至少一個表或
視圖的所有行,只要這些行符合任何 WHERE 或 HAVING 搜索條件。將檢索通過左向外聯接引用的左表的所有行,以及通過右向外聯接引用的右表的所有行。完整外
部聯接中兩個表的所有行都將返回。
五、子查詢
以一個查詢select的結果作為另一個查詢的條件
語法:select * from 表1 wher 條件1(select ..from 表2 where 條件2)
1、與In結合
- select?*?from?STUDENT?where?STU_ID?IN(select?STU_ID?from?GRADE?where?STU_SCORE>85);??
2、與EXISTS結合
EXISTS和NOT EXISTS操作符只測試某個子查詢是否返回了數據行。如果是,EXISTS將是true,NOT EXISTS將是false。
- select?*?from?STUDENT?where??EXISTS?(select?STU_ID?from?GRADE?where?STU_SCORE>=100);??
3、ALL、ANY和SOME子查詢
any和all的操作符常見用法是結合一個相對比較操作符對一個數據列子查詢的結果進行測試。它們測試比較值是否與子查詢所返回的全部或一部分值匹配。比方說,如果比較值小于或等于子查詢所返回的每一個值,<=all將是true,只要比較值小于或等于子查詢所返回的任何一個值,<=any將是true。some是any的一個同義詞。
- select?STU_ID?from?GRADE?where?STU_SCORE?<67;??

只要學號大于上面的任意一個就顯示出來:
- select?*?from?STUDENT?where?STU_ID?>=?any?(select?STU_ID?from?GRADE?where?STU_SCORE?<67);??

六、合并查詢結果
合并查詢結果是將多個SELECT語句的查詢結果合并到一起。因為某種情況下,需要將幾個SELECT語句查詢出來的結果合并起來顯示。
使用UNION關鍵字時,數據庫系統會將所有的查詢結果合并到一起,然后去除掉相同的記錄。而UNION ALL關鍵字則只是簡單的合并到一起。其語法規則如下:
- SELECT語句1??
- UNION?|?UNION?ALL??
- SELECT語句2??
- UNION?|?UNION?ALL?….??
- SELECT語句n?;??
七、排序與取數
7.1、order by
(1) order by price //默認升序排列
(2)order by price desc //降序排列
(3)order by price asc //升序排列,與默認一樣
(4)order by rand() //隨機排列,效率不高
- select?*?from?GRADE?where?STU_SCORE?>80?order?by?STU_SCORE;??
默認是按升序的,
也可以這么寫
- select?*?from?GRADE?where?STU_SCORE?>80?order?by?STU_SCORE?ASC;??
如果想換成降序的:
- select?*?from?GRADE?where?STU_SCORE?>80?order?by?STU_SCORE?desc;??

7.2、limit
limit [offset,] N
offset 偏移量,可選,不寫則相當于limit 0,N
N 取出條目?
取分數最高的前5條
- select?*?from?GRADE?order?by?STU_SCORE?desc?limit?5;??

取分數最低的前5條
- select?*?from?GRADE?order?by?STU_SCORE?asc?limit?5;??
取分數排名在10-15之間的5條
- select?*?from?GRADE?order?by?STU_SCORE?desc?limit?10,5??
八、為表和字段取別名
使用AS來命名列
- select?STU_ID?as?'學號',STU_SCORE?as?'分數'?from?GRADE;??
當表的名稱特別長時,在查詢中直接使用表名很不方便。這時可以為表取一個別名。用這個別名來代替表的名稱。
MySQL中為表取別名的基本形式如下:
表名 表的別名
- select?S.STU_ID,S.STU_NAME,S.STU_AGE,S.STU_SEX,G.STU_SCORE?from?STUDENT?S,GRADE?G?WHERE?S.STU_ID=G.STU_ID?AND?G.STU_SCORE?>=90;??

九、使用正則表達式查詢
??????? 正則表達式是用某種模式去匹配一類字符串的一個方式。例如,使用正則表達式可以查詢出包含A、B、C其中任一字母的字符串。正則表達式的查詢能力比通配字符的查詢能力更強大,而且更加的靈活。正則表達式可以應用于非常復雜查詢。
MySQL中,使用REGEXP關鍵字來匹配查詢正則表達式。其基本形式如下:
屬性名 REGEXP '匹配方式'
在使用前先插入一些數據:
- insert??into?STUDENT?values(2022,'12wef',13,'男');??
- insert??into?STUDENT?values(2023,'faf_23',13,'男');??
- insert??into?STUDENT?values(2024,'fafa',13,'女');??
- insert??into?STUDENT?values(2025,'ooop',14,'男');??
- insert??into?STUDENT?values(2026,'23oop',14,'男');??
- insert??into?STUDENT?values(2027,'woop89',14,'男');??
- insert??into?STUDENT?values(2028,'abcdd',11,'男');??
(1)使用字符“^”可以匹配以特定字符或字符串開頭的記錄。
查詢所有以阿頭的
- select?*?from?STUDENT?where?STU_NAME?REGEXP??'^阿';??

- select?*?from?STUDENT?where?STU_NAME?REGEXP?'^[0-9]';??
(2)使用字符“$”可以匹配以特定字符或字符串結尾的記錄
以數字結尾
- select?*?from?STUDENT?where?STU_NAME?REGEXP?'[0-9]$';??
(3)用正則表達式來查詢時,可以用“.”來替代字符串中的任意一個字符。
- select?*?from?STUDENT?where?STU_NAME?REGEXP?'^w....[0-9]$';??
(4)使用方括號([])可以將需要查詢字符組成一個字符集。只要記錄中包含方括號中的任意字符,該記錄將會被查詢出來。
例如,通過“[abc]”可以查詢包含a、b、c這三個字母中任何一個的記錄。
使用方括號可以指定集合的區間。
“[a-z]”表示從a-z的所有字母;
“[0-9]”表示從0-9的所有數字;
“[a-z0-9]”表示包含所有的小寫字母和數字。
“[a-zA-Z]”表示匹配所有字母。
- select?*?from?STUDENT?where?STU_NAME?REGEXP?'[0-9a-z]';??
使用“[^字符集合]”可以匹配指定字符以外的字符
(5){}表示出現的次數
正則表達式中,“字符串{M}”表示字符串連續出現M次;“字符串{M,N}”表示字符串聯連續出現至少M次,最多N次。例如,“ab{2}”表示字符串“ab”連續出現兩次。“ab{2,4}”表示字符串“ab”連續出現至少兩次,最多四次。
o出現2次
- select?*?from?STUDENT?where?STU_NAME?REGEXP?'o{2}';??
(6)+表示到少出現一次
fa至少出現一次
- select?*?from?STUDENT?where?STU_NAME?REGEXP?'(fa)+';??

???????
?注意:??
?????? 正則表達式可以匹配字符串。當表中的記錄包含這個字符串時,就可以將該記錄查詢出來。如果指定多個字符串時,需要用符號“|”隔開。只要匹配這些字符串中的任意一個即可。每個字符串與”|”之間不能有空格。因為,查詢過程中,數據庫系統會將空格也當作一個字符。這樣就查詢不出想要的結果。
正則表達式中,“*”和“+”都可以匹配多個該符號之前的字符。但是,“+”至少表示一個字符,而“*”可以表示零個字符。