1. 程式人生 > >mysql四-1:單表查詢

mysql四-1:單表查詢

單表查詢

一、單表查詢的語法

SELECT 字段1,字段2... FROM 表名

WHERE 條件

GROUP BY field

HAVING 篩選

ORDER BY field

LIMIT 限制條數


二、關鍵字的執行優先級(重點)

關鍵字的執行優先級 重點中的重點!!!

from--->where--->group by--->having--->select--->distinct--->order by--->limit

1.找到表:from

2.拿著where指定的約束條件,去文件/表中取出一條條記錄

3.將取出的一條條記錄進行分組group by,如果沒有group by,則整體作為一組

4.將分組的結果進行having過濾

5.執行select

6.去重

7.將結果按條件排序:order by

8.限制結果的顯示條

三、簡單查詢

1、造表

創建表

mysql> create table employee(

id int not null unique auto_increment,

name varchar(20) not null,

sex enum('male','female') not null default 'male', #大部分是男的

age int(3) unsigned not null default 28,

hire_date date not null,

post varchar(50),

post_comment varchar(100),

salary double(15,2),

office int, #一個部門一個屋子

depart_id int

);

查看表結構

mysql> desc employee;

插入記錄(三個部門:教學,銷售,運營)

mysql> insert into employee(name,sex,age,hire_date,post,salary,office,depart_id) values

('egon','male',18,'20170301','老男孩駐沙河辦事處外交大使',7300.33,401,1), #以下是教學部

('alex','male',78,'20150302','teacher',1000000.31,401,1),

('wupeiqi','male',81,'20130305','teacher',8300,401,1),

('yuanhao','male',73,'20140701','teacher',3500,401,1),

('liwenzhou','male',28,'20121101','teacher',2100,401,1),

('jingliyang','female',18,'20110211','teacher',9000,401,1),

('jinxin','male',18,'19000301','teacher',30000,401,1),

('成龍','male',48,'20101111','teacher',10000,401,1),

('歪歪','female',48,'20150311','sale',3000.13,402,2),#以下是銷售部門

('丫丫','female',38,'20101101','sale',2000.35,402,2),

('丁丁','female',18,'20110312','sale',1000.37,402,2),

('星星','female',18,'20160513','sale',3000.29,402,2),

('格格','female',28,'20170127','sale',4000.33,402,2),

('張野','male',28,'20160311','operation',10000.13,403,3), #以下是運營部門

('程咬金','male',18,'19970312','operation',20000,403,3),

('程咬銀','female',18,'20130311','operation',19000,403,3),

('程咬銅','male',18,'20150411','operation',18000,403,3),

('程咬鐵','female',18,'20140512','operation',17000,403,3)

;

2、查詢

簡單查詢

SELECT id,name,sex,age,hire_date,post,post_comment,salary,office,depart_id FROM employee;

SELECT * FROM employee;

SELECT name,salary FROM employee;

避免重復DISTINCT

SELECT DISTINCT post FROM employee; #distinct意思是輸出後面 列 去重後的內容;

通過四則運算查詢

SELECT name, salary*12 FROM employee;

SELECT name, salary*12 AS Annual_salary FROM employee;

SELECT name, salary*12 Annual_salary FROM employee;

定義顯示格式

#CONCAT() 函數用於連接字符串

SELECT CONCAT('姓名: ',name,' 年薪: ', salary*12) AS Annual_salary FROM employee;

#CONCAT_WS() 第一個參數為分隔符

SELECT CONCAT_WS(':',name,salary*12) AS Annual_salary FROM employee;

結合CASE語句:

SELECT

(

CASE

WHEN NAME = 'egon' THEN

NAME

WHEN NAME = 'alex' THEN

CONCAT(name,'_BIGSB')

ELSE

concat(NAME, 'SB')

END

) as new_name

FROM employee;

3、小練習

1)查出所有員工的名字,薪資,格式為

<名字:egon> <薪資:3000>

SELECT CONCAT('<名字:',name,'> ','<年薪:',salary*12,'>') AS annual_year FROM employee;

2)查出所有的崗位(去掉重復)

SELECT DISTINCT depart_id FROM employee;

3)查出所有員工名字,以及他們的年薪,年薪的字段名為annual_year

SELECT name, salary*12 AS annual_year FROM employee;


四、WHERE約束

where字句中可以使用:

1. 比較運算符:> < >= <= <> !=

2. between 80 and 100 值在10到20之間

3. in(80,90,100) 值是10或20或30

4. like 'egon%'

pattern可以是%或_(%表示任意多字符,_表示一個字符)

5. 邏輯運算符:在多個條件直接可以使用邏輯運算符 and or not

單條件查詢:

SELECT name FROM employee WHERE post='sale';

多條件查詢:

SELECT name,salary FROM employee WHERE post='teacher' AND salary>10000;

關鍵字BETWEEN AND:

SELECT name,salary FROM employee WHERE salary BETWEEN 10000 AND 20000;

SELECT name,salary FROM employee WHERE salary NOT BETWEEN 10000 AND 20000;

關鍵字IS NULL(判斷某個字段是否為NULL不能用等號,需要用IS):

SELECT name,post_comment FROM employee WHERE post_comment IS NULL;

SELECT name,post_comment FROM employee WHERE post_comment IS NOT NULL;

SELECT name,post_comment FROM employee WHERE post_comment=''; 註意''是空字符串,不是null

ps:

執行update employee set post_comment='' where id=2;再用上條查看,就會有結果了

關鍵字IN集合查詢:

SELECT name,salary FROM employee WHERE salary=3000 OR salary=3500 OR salary=4000 OR salary=9000 ;

SELECT name,salary FROM employee WHERE salary IN (3000,3500,4000,9000) ;

SELECT name,salary FROM employee WHERE salary NOT IN (3000,3500,4000,9000) ;

關鍵字LIKE模糊查詢:

通配符’%’:SELECT * FROM employee WHERE name LIKE 'eg%';

通配符’_’:SELECT * FROM employee WHERE name LIKE 'al__';

小練習:

1. 查看崗位是teacher的員工姓名、年齡

SELECT name,age FROM employee WHERE post='teacher';

2. 查看崗位是teacher且年齡大於30歲的員工姓名、年齡

SELECT name,age FROM employee WHERE post='teacher' AND age>30;

3. 查看崗位是teacher且薪資在9000-1000範圍內的員工姓名、年齡、薪資

SELECT name,age,salary FROM employee WHERE post='teacher' AND salary between 9000 and 10000;

4. 查看崗位描述不為NULL的員工信息

select * from employee where post_comment is not null;

5. 查看崗位是teacher且薪資是10000或9000或30000的員工姓名、年齡、薪資

SELECT name,age,salary FROM employee WHERE post='teacher' AND salary in (10000,9000,30000);

6. 查看崗位是teacher且薪資不是10000或9000或30000的員工姓名、年齡、薪資

SELECT name,age,salary FROM employee WHERE post='teacher' AND salary not in (10000,9000,30000);

7. 查看崗位是teacher且名字是jin開頭的員工姓名、年薪

SELECT name,salary FROM employee WHERE post='teacher' AND age like 'jin%';


五、分組查詢:GROUP BY

1、什麽是分組?為什麽要分組?

1)首先明確一點:分組發生在where之後,即分組是基於where之後得到的記錄而進行的

2)分組指的是:將所有記錄按照某個相同字段進行歸類,比如針對員工信息表的職位分組,或者按照性別進行分組等

3)為何要分組呢?

取每個部門的最高工資

取每個部門的員工數

取男人數和女人數

小竅門:‘每’這個字後面的字段,就是我們分組的依據

4)大前提:

可以按照任意字段分組,但是分組完畢後,比如group by post,只能查看post字段,如果想查看組內信息,需要借助於聚合函數

2、ONLY_FULL_GROUP_BY

查看MySQL 5.7默認的sql_mode如下:

mysql> select @@global.sql_mode;

ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

!!!註意

ONLY_FULL_GROUP_BY的語義就是確定select target list中的所有列的值都是明確語義,簡單的說來,在ONLY_FULL_GROUP_BY模式下,target list中的值要麽是來自於聚集函數的結果,要麽是來自於group by list中的表達式的值。

設置sql_mole如下操作(我們可以去掉ONLY_FULL_GROUP_BY模式):

mysql> set global sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';

3、GROUP BY

單獨使用GROUP BY關鍵字分組

SELECT post FROM employee GROUP BY post;

註意:我們按照post字段分組,那麽select查詢的字段只能是post,想要獲取組內的其他相關信息,需要借助函數

GROUP BY關鍵字和GROUP_CONCAT()函數一起使用

SELECT post,GROUP_CONCAT(name) FROM employee GROUP BY post;#按照崗位分組,並查看組內成員名

SELECT post,GROUP_CONCAT(name) as emp_members FROM employee GROUP BY post;

GROUP BY與聚合函數一起使用

select post,count(id) as count from employee group by post;#按照崗位分組,並查看每個組有多少人

4、聚合函數

強調:聚合函數聚合的是組的內容,若是沒有分組,則默認一組

示例:

SELECT COUNT(*) FROM employee;

SELECT COUNT(*) FROM employee WHERE depart_id=1;

SELECT MAX(salary) FROM employee;

SELECT MIN(salary) FROM employee;

SELECT AVG(salary) FROM employee;

SELECT SUM(salary) FROM employee;

SELECT SUM(salary) FROM employee WHERE depart_id=3;

5、小練習:

1)查詢崗位名以及崗位包含的所有員工名字

SELECT post,GROUP_CONCAT(name) FROM employee GROUP BY post;

2)查詢崗位名以及各崗位內包含的員工個數

SELECT post,count(id) FROM employee GROUP BY post;

3)查詢公司內男員工和女員工的個數

SELECT sex,count(id) FROM employee GROUP BY sex;

4)查詢崗位名以及各崗位的平均薪資

SELECT post,AVG(salary) FROM employee GROUP BY post;

5)查詢崗位名以及各崗位的最高薪資

SELECT post,MAX(salary) FROM employee GROUP BY post;

6)查詢崗位名以及各崗位的最低薪資

SELECT post,MIN(salary) FROM employee GROUP BY post;

7)查詢男員工與男員工的平均薪資,女員工與女員工的平均薪資

SELECT sex,AVG(salary) FROM employee GROUP BY sex;


六、HAVING過濾

HAVING與WHERE不一樣的地方在於!!!!!!

!!!執行優先級從高到低:where > group by > having

1. Where 發生在分組group by之前,因而Where中可以有任意字段,但是絕對不能使用聚合函數。

2. Having發生在分組group by之後,因而Having中可以使用分組的字段,無法直接取到其他字段,可以使用聚合函數

小練習:

1. 查詢各崗位內包含的員工個數小於2的崗位名、崗位內包含員工名字、個數

SELECT post,group_concat(name),count(id) FROM employee GROUP BY post having count(id)<2;

3. 查詢各崗位平均薪資大於10000的崗位名、平均工資

SELECT post,AVG(salary) FROM employee GROUP BY post having AVG(salary)>10000;

4. 查詢各崗位平均薪資大於10000且小於20000的崗位名、平均工資

SELECT post,AVG(salary) FROM employee GROUP BY post having AVG(salary)>10000 and AVG(salary)<20000;


七、查詢排序:ORDER BY

按單列排序

SELECT * FROM employee ORDER BY salary;

SELECT * FROM employee ORDER BY salary ASC;

SELECT * FROM employee ORDER BY salary DESC;

按多列排序:先按照age排序,如果年紀相同,則按照薪資排序

SELECT * from employee ORDER BY age,salary DESC;

小練習:

1. 查詢所有員工信息,先按照age升序排序,如果age相同則按照hire_date降序排序

SELECT * from employee ORDER BY age,hire_date DESC;

2. 查詢各崗位平均薪資大於10000的崗位名、平均工資,結果按平均薪資升序排列

SELECT post,avg(salary) from employee group by post having avg(salary)>10000 ORDER BY avg(salary);

3. 查詢各崗位平均薪資大於10000的崗位名、平均工資,結果按平均薪資降序排列

SELECT post,avg(salary) from employee group by post having avg(salary)>10000 ORDER BY avg(salary) DESC;


八、限制查詢的記錄數:LIMIT

示例:

SELECT * FROM employee ORDER BY salary DESC LIMIT 3; #默認初始位置為0

SELECT * FROM employee ORDER BY salary DESC LIMIT 0,5; #從第0開始,即先查詢出第一條,然後包含這一條在內往後查5條

SELECT * FROM employee ORDER BY salary DESC LIMIT 5,5; #從第5開始,即先查詢出第6條,然後包含這一條在內往後查5條

小練習:

1. 分頁顯示,每頁5條

SELECT * FROM employee ORDER BY salary DESC LIMIT 0,5;

SELECT * FROM employee ORDER BY salary DESC LIMIT 5,5;

SELECT * FROM employee ORDER BY salary DESC LIMIT 10,5;


九、使用正則表達式查詢

SELECT * FROM employee WHERE name REGEXP '^ale';

SELECT * FROM employee WHERE name REGEXP 'on$';

SELECT * FROM employee WHERE name REGEXP 'm{2}';

小結:對字符串匹配的方式

WHERE name = 'egon';

WHERE name LIKE 'yua%';

WHERE name REGEXP 'on$';

小練習:

查看所有員工中名字是jin開頭,n或者g結果的員工信息

SELECT * FROM employee WHERE name REGEXP '^jin.*[gn]';


mysql四-1:單表查詢