1. 程式人生 > >mysql--單表查詢---語句與語法

mysql--單表查詢---語句與語法

cte 。。 for 居中 默認 quit 性別 lec hang

一、單表查詢的語法

select 字段1,字段2,字段3.。。from 表名

                  where 條件
                  group by field 分領域(組)查詢

                  having 篩選

                  distinct 避免重復

                  order by field 排序查詢

                  limit 限制條件查詢

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

重點中的重點:

1、where

2、group by

3、having

4、select

5、distinct

6、order by

7、limit

a、找到表:from

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

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

d、將分組的結果進行having過濾

e、執行select

f、distinct去重

g、將結果按條件進行:order by

h、限制結果的顯示條數

三、簡單查詢

技術分享
 1 company.employee
 2     員工id      id                  int             
 3     姓名        emp_name            varchar
4 性別 sex enum 5 年齡 age int 6 入職日期 hire_date date 7 崗位 post varchar 8 職位描述 post_comment varchar 9 薪水 salary double 10 辦公室 office int 11 部門編號 depart_id int
12 13 14 15 #創建表 16 create table employee( 17 id int not null unique auto_increment, 18 name varchar(20) not null, 19 sex enum(male,female) not null default male, #大部分是男的 20 age int(3) unsigned not null default 28, 21 hire_date date not null, 22 post varchar(50), 23 post_comment varchar(100), 24 salary double(15,2), 25 office int, #一個部門一個屋子 26 depart_id int 27 ); 28 29 30 #查看表結構 31 mysql> desc employee; 32 +--------------+-----------------------+------+-----+---------+----------------+ 33 | Field | Type | Null | Key | Default | Extra | 34 +--------------+-----------------------+------+-----+---------+----------------+ 35 | id | int(11) | NO | PRI | NULL | auto_increment | 36 | name | varchar(20) | NO | | NULL | | 37 | sex | enum(male,female) | NO | | male | | 38 | age | int(3) unsigned | NO | | 28 | | 39 | hire_date | date | NO | | NULL | | 40 | post | varchar(50) | YES | | NULL | | 41 | post_comment | varchar(100) | YES | | NULL | | 42 | salary | double(15,2) | YES | | NULL | | 43 | office | int(11) | YES | | NULL | | 44 | depart_id | int(11) | YES | | NULL | | 45 +--------------+-----------------------+------+-----+---------+----------------+ 46 47 #插入記錄 48 #三個部門:教學,銷售,運營 49 insert into employee(name,sex,age,hire_date,post,salary,office,depart_id) values 50 (egon,male,18,20170301,老男孩駐沙河辦事處外交大使,7300.33,401,1), #以下是教學部 51 (alex,male,78,20150302,teacher,1000000.31,401,1), 52 (wupeiqi,male,81,20130305,teacher,8300,401,1), 53 (yuanhao,male,73,20140701,teacher,3500,401,1), 54 (liwenzhou,male,28,20121101,teacher,2100,401,1), 55 (jingliyang,female,18,20110211,teacher,9000,401,1), 56 (jinxin,male,18,19000301,teacher,30000,401,1), 57 (成龍,male,48,20101111,teacher,10000,401,1), 58 59 (歪歪,female,48,20150311,sale,3000.13,402,2),#以下是銷售部門 60 (丫丫,female,38,20101101,sale,2000.35,402,2), 61 (丁丁,female,18,20110312,sale,1000.37,402,2), 62 (星星,female,18,20160513,sale,3000.29,402,2), 63 (格格,female,28,20170127,sale,4000.33,402,2), 64 65 (張野,male,28,20160311,operation,10000.13,403,3), #以下是運營部門 66 (程咬金,male,18,19970312,operation,20000,403,3), 67 (程咬銀,female,18,20130311,operation,19000,403,3), 68 (程咬銅,male,18,20150411,operation,18000,403,3), 69 (程咬鐵,female,18,20140512,operation,17000,403,3) 70 ; 71 72 #ps:如果在windows系統中,插入中文字符,select的結果為空白,可以將所有字符編碼統一設置成gbk
例子:準備表和記錄 技術分享
#簡單查詢
select id,name,sex...from employee;
select * from employee;
select name,age from employee;

#避免重復 distinct
select distinct post from employee;

#通過四則運算查詢
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;

#查出所有員工的名字,薪資,格式為<名字:egon> <薪資:3000>
select concat(<名字:,name,>    ,<薪資:,salary,>) from employee;

#查出所有的崗位(去掉重復)
select distinct depart_id from employee;

#查出所有員工名字,以及他們的年薪,年薪的字段名為annual_salary
簡單查詢

四、where 約束

where自居中可以使用:

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

2、between 80 and 100值在80到100之間

3、in(80,90,100)值是80,90或100

4、like ‘egon%’

  pattern 可以是% 或_,

  %表示任意多字符,_表示一個字符,其中_最多為3個。

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

技術分享
#1、單條件查詢
select name from employee where post=sale;

#2、多條件查詢
select name,salary from employee where post=teacher and salary>10000;

#3、關鍵字between and
select name,salary from employee where salary between 5000 and 20000;
select name,salary from employee where salary not between 5000 and 20000;

#4、關鍵字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;
    再用上條查看就有結果了。
where約束 技術分享
#5、關鍵字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(300,3500,4000,9000);
select name,salary from employee where salary not in(300,3500,4000,9000);

#6、關鍵字like模糊查詢
通配符‘%’
select * from employee where name like eg%;
select * from employee where post like tea%;

通配符_
select * from employee where name like a___;
select * from employee where name like wu_____;
select * from employee where name like ______;
where 約束2
1. 查看崗位是teacher的員工姓名、年齡
2. 查看崗位是teacher且年齡大於30歲的員工姓名、年齡
3. 查看崗位是teacher且薪資在9000-1000範圍內的員工姓名、年齡、薪資
4. 查看崗位描述不為NULL的員工信息
5. 查看崗位是teacher且薪資是10000或9000或30000的員工姓名、年齡、薪資
6. 查看崗位是teacher且薪資不是10000或9000或30000的員工姓名、年齡、薪資
7. 查看崗位是teacher且名字是jin開頭的員工姓名、年薪
1、select name,age from employee where post=teacher;
2、select name,age from employee where post=teacherand age>30;
3、select name,age,salary from employee where post=teacherand salary between 9000 and 10000;
4、select * from employee where post_comment is not null;
5、select name,age,salary from employee where post=teacherand salary in(10000,9000,30000);
6、select name,age,salary from employee where post=teacherand salary not in(10000,9000,30000);
7、select name,age,salary from employee where post=teacher and name like jin%;

五 分組查詢:group by

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

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

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

#3、為什麽要分組?
取每個部門的最高工資
取每個部門的員工數
取男人數和女人數
小竅門:’每’這個字後面的字段,就是我們分組的依據

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

二 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;

!!!SQL_MODE設置!!!
mysql> select @@global.sql_mode;
+-------------------+
| @@global.sql_mode |
+-------------------+
|                   |
+-------------------+
row in set (0.00 sec)

mysql> select * from emp group by post; 
+----+------+--------+-----+------------+----------------------------+--------------+------------+--------+-----------+
| id | name | sex    | age | hire_date  | post                       | post_comment | salary     | office | depart_id |
+----+------+--------+-----+------------+----------------------------+--------------+------------+--------+-----------+
| 14 | 張野 | male   |  28 | 2016-03-11 | operation                  | NULL         |   10000.13 |    403 |         3 |
|  9 | 歪歪 | female |  48 | 2015-03-11 | sale                       | NULL         |    3000.13 |    402 |         2 |
|  2 | alex | male   |  78 | 2015-03-02 | teacher                    | NULL         | 1000000.31 |    401 |         1 |
|  1 | egon | male   |  18 | 2017-03-01 | 老男孩駐沙河辦事處外交大使 | NULL         |    7300.33 |    401 |         1 |
+----+------+--------+-----+------------+----------------------------+--------------+------------+--------+-----------+
rows in set (0.00 sec)


#由於沒有設置ONLY_FULL_GROUP_BY,於是也可以有結果,默認都是組內的第一條記錄,但其實這是沒有意義的

mysql> set global sql_mode=ONLY_FULL_GROUP_BY;
Query OK, 0 rows affected (0.00 sec)

mysql> quit #設置成功後,一定要退出,然後重新登錄方可生效
Bye

mysql> use db1;
Database changed
mysql> select * from emp group by post; #報錯
ERROR 1055 (42000): db1.emp.id isnt in GROUP BY
mysql> select post,count(id) from emp group by post; #只能查看分組依據和使用聚合函數
+----------------------------+-----------+
| post                       | count(id) |
+----------------------------+-----------+
| operation                  |         5 |
| sale                       |         5 |
| teacher                    |         7 |
| 老男孩駐沙河辦事處外交大使 |         1 |
+----------------------------+-----------+
rows in set (0.00 sec)

三 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) names from employee group by post;

group by與聚合函數一起使用
    select post,count(id) as count from employee group by post;#按照崗位分組,並查看每個組有多少人

強調:

如果我們用unique的字段作為分組的依據,則每一條記錄自成一組,這種分組沒有意義
多條記錄之間的某個字段值相同,該字段通常用來作為分組的依據

四 聚合函數

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

示例:
    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;

五 小練習:

1. 查詢崗位名以及崗位包含的所有員工名字
2. 查詢崗位名以及各崗位內包含的員工個數
3. 查詢公司內男員工和女員工的個數
4. 查詢崗位名以及各崗位的平均薪資
5. 查詢崗位名以及各崗位的最高薪資
6. 查詢崗位名以及各崗位的最低薪資
7. 查詢男員工與男員工的平均薪資,女員工與女員工的平均薪資
1、select post,group_concat(name) from employee group by  post;
2、select post,count(name) 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中可以使用分組的字段,無法直接取到其他字段,可以使用聚合函數
技術分享
mysql> select @@sql_mode;
+--------------------+
| @@sql_mode         |
+--------------------+
| ONLY_FULL_GROUP_BY |
+--------------------+
row in set (0.00 sec)

mysql> select * from emp where salary > 100000;
+----+------+------+-----+------------+---------+--------------+------------+--------+-----------+
| id | name | sex  | age | hire_date  | post    | post_comment | salary     | office | depart_id |
+----+------+------+-----+------------+---------+--------------+------------+--------+-----------+
|  2 | alex | male |  78 | 2015-03-02 | teacher | NULL         | 1000000.31 |    401 |         1 |
+----+------+------+-----+------------+---------+--------------+------------+--------+-----------+
row in set (0.00 sec)

mysql> select * from emp having salary > 100000;
ERROR 1463 (42000): Non-grouping field salary is used in HAVING clause

mysql> select post,group_concat(name) from emp group by post having salary > 10000;#錯誤,分組後無法直接取到salary字段
ERROR 1054 (42S22): Unknown column salary in having clause
mysql> select post,group_concat(name) from emp group by post having avg(salary) > 10000;
+-----------+-------------------------------------------------------+
| post | group_concat(name) |
+-----------+-------------------------------------------------------+
| operation | 程咬鐵,程咬銅,程咬銀,程咬金,張野 |
| teacher | 成龍,jinxin,jingliyang,liwenzhou,yuanhao,wupeiqi,alex |
+-----------+-------------------------------------------------------+
rows in set (0.00 sec)
驗證

小練習

1. 查詢各崗位內包含的員工個數小於2的崗位名、崗位內包含員工名字、個數
3. 查詢各崗位平均薪資大於10000的崗位名、平均工資
4. 查詢各崗位平均薪資大於10000且小於20000的崗位名、平均工資
1、select post,group_concat(name),count(id) from employee group by post having count(id)<2;
2、select post,avg(salary) from employee group by post having avg(salary) >10000;
3、select post,avg(salary) from employee group by post having avg(salary) between 10000 and 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降序排序
2. 查詢各崗位平均薪資大於10000的崗位名、平均工資,結果按平均薪資升序排列
3. 查詢各崗位平均薪資大於10000的崗位名、平均工資,結果按平均薪資降序排列
1、select * from employee order by age,hire_date desc;
2、select post,avg(salary) from employee group by post having avg(salary)>10000 order by  avg(salary) ;

八、限制查詢的記錄數: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 limit 0,5;
select * from employee limit 5,5;
select * from employee 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.*[ng]$ ;

mysql--單表查詢---語句與語法