林炳文Evankaka原創做品。轉載請註明出處http://blog.csdn.net/evankaka
mysql
查詢數據指從數據庫中獲取所需要的數據。查詢數據是數據庫操做中最常用,也是最重要的操做。用戶可以依據本身對數據的需求,使用不一樣的查詢方式。經過不一樣的查詢方式,可以得到不一樣的數據。sql
MySQL中是使用SELECT語句來查詢數據的。數據庫
在這一章中將解說的內容包括。
一、查詢語句的基本的語法
二、在單表上查詢數據
三、使用聚合函數查詢數據
四、多表上聯合查詢
五、子查詢
六、合併查詢結果
七、爲表和字段取別名
八、使用正則表達式查詢函數
什麼是查詢?oop
怎麼查的?post
數據的準備例如如下:
spa
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語句來查詢數據。.net
依據查詢條件的不一樣,數據庫系統會找到不一樣的數據。code
SELECT語句的基本的語法格式例如如下:blog
SELECT 屬性列表 FROM 表名或視圖列表 [WHERE 條件表達式1] [GROUP BY 屬性名1 [HAVING 條件表達式2]] [ORDER BY 屬性名2 [ASC|DESC]]
即表示值依照從小到大的順序排列。這是默認參數。
假設有WHERE子句。就依照「條件表達式1」指定的條件進行查詢;假設沒有WHERE子句,就查詢所有記錄。
假設有GROUP BY子句,就依照「屬性名1」指定的字段進行分組。假設GROUP BY子句後面帶着HAVINGkeyword。那麼僅僅有知足「條件表達式2」中指定的條件的記錄才幹夠輸出。
GROUP BY子句一般和COUNT()、SUM()等聚合函數一塊兒使用。
假設有ORDER BY子句,就依照「屬性名2」指定的字段進行排序。排序方式由ASC或DESC參數指定。
默認的排序方式爲ASC。
select * from STUDENT;
select * from STUDENT where STU_AGE>13;
假設字段的值在集合中,則知足查詢條件。該紀錄將被查詢出來。假設不在集合中。則不知足查詢條件。其語法規則例如如下:[ NOT ] IN ( 元素1, 元素2, …, 元素n )
select * from STUDENT where STU_AGE in(11,12);
select * from STUDENT where STU_AGE between 13 and 15;
select * from STUDENT where STU_AGE NOT IN(13,14,16);
使用ORkeyword時,僅僅要知足這幾個查詢條件的當中一個,這種記錄將會被查詢出來。假設不知足這些查詢條件中的不論什麼一個,這種記錄將被排除掉。ORkeyword的語法規則例如如下:
條件表達式1 OR 條件表達式2 [ …OR 條件表達式n ]
當中。OR可以用來鏈接兩個條件表達式。而且,可以同一時候使用多個ORkeyword,這樣可以鏈接不少其它的條件表達式。
select * from STUDENT where STU_ID<2005 OR STU_ID>2015;
使用ANDkeyword時,僅僅有同一時候知足所有查詢條件的記錄會被查詢出來。
假設不知足這些查詢條件的當中一個,這種記錄將被排除掉。
ANDkeyword的語法規則例如如下:
條件表達式1 AND 條件表達式2 [ … AND 條件表達式n ]
當中,AND可以鏈接兩個條件表達式。而且,可以同一時候使用多個ANDkeyword,這樣可以鏈接不少其它的條件表達式。
假設與指定的字符串不匹配。則不知足查詢條件。
其語法規則例如如下:[ 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 NULLkeyword可以用來推斷字段的值是否爲空值(NULL)。
假設字段的值是空值。則知足查詢條件,該記錄將被查詢出來。假設字段的值不是空值,則不知足查詢條件。其語法規則例如如下:
IS [ NOT ] NULL
當中,「NOT」是可選參數。加上NOT表示字段不是空值時知足條件。
IS NULL是一個整體,不能將IS換成」=」.
例如如下:
select * from STUDENT group by STU_SEX;不加條件,那麼就僅僅取每個分組的第一條。
假設想看分組的內容,可以加groub_concat
select STU_SEX,group_concat(STU_NAME) from STUDENT group by STU_SEX;
先準備一些數據:
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;
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;查找平均工資大於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;查找大於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)
一、與In結合
select * from STUDENT where STU_ID IN(select STU_ID from GRADE where STU_SCORE>85);查找大於85分的學生信息
二、與EXISTS結合
EXISTS和NOT EXISTS操做符僅僅測試某個子查詢是否返回了數據行。假設是,EXISTS將是true,NOT EXISTS將是false。
select * from STUDENT where EXISTS (select STU_ID from GRADE where STU_SCORE>=100);假設有學生成績大於100,才查詢所有的學生信息
三、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語句查詢出來的結果合併起來顯示。
使用UNIONkeyword時,數據庫系統會將所有的查詢結果合併到一塊兒,而後去除掉一樣的記錄。而UNION ALLkeyword則僅僅是簡單的合併到一塊兒。其語法規則例如如下:
SELECT語句1 UNION | UNION ALL SELECT語句2 UNION | UNION ALL …. SELECT語句n ;
(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;
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中,使用REGEXPkeyword來匹配查詢正則表達式。其基本形式例如如下:
屬性名 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]$';以w開頭,以數字結束。中間有4個
(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)+';
注意:
正則表達式可以匹配字符串。當表中的記錄包括這個字符串時,就可以將該記錄查詢出來。
假設指定多個字符串時。需要用符號「|」隔開。僅僅要匹配這些字符串中的隨意一個就能夠。每個字符串與」|」之間不能有空格。
因爲。查詢過程當中,數據庫系統會將空格也看成一個字符。這樣就查詢不出想要的結果。
正則表達式中,「*」和「+」都可以匹配多個該符號以前的字符。但是,「+」至少表示一個字符,而「*」可以表示零個字符。