介紹
存儲引擎決定了表的類型,而表內存放的數據也要有不一樣的類型,每種數據類型都有本身的寬度,但寬度是可選的html
詳細參考連接:http://www.runoob.com/mysql/mysql-data-types.htmlmysql
mysql經常使用數據類:sql
#1. 數字: 整型:tinyint int bigint 小數: float :在位數比較短的狀況下不精準 double :在位數比較長的狀況下不精準 0.000001230123123123 存成:0.000001230000 decimal:(若是用小數,則用推薦使用decimal) 精準 內部原理是以字符串形式去存 #2. 字符串: char(10):簡單粗暴,浪費空間,存取速度快 root存成root000000 varchar:精準,節省空間,存取速度慢 sql優化:建立表時,定長的類型往前放,變長的日後放 好比性別 好比地址或描述信息 >255個字符,超了就把文件路徑存放到數據庫中。 好比圖片,視頻等找一個文件服務器,數據庫中只存路徑或url。 #3. 時間類型: 最經常使用:datetime #4. 枚舉類型與集合類型 enum 和set
一 . 數值類型
整數類型 : tinyint , smallint , mediumint , int , bigint 數據庫
做用 : 存儲年齡 , 等級(好比騰訊的 vip ,svip....) , id , 各類號碼等服務器


======================================== tinyint[(m)] [unsigned] [zerofill] 小整數,數據類型用於保存一些範圍的整數數值範圍: 有符號: -128 ~ 127 無符號: ~ 255 PS: MySQL中無布爾值,使用tinyint(1)構造。 ======================================== int[(m)][unsigned][zerofill] 整數,數據類型用於保存一些範圍的整數數值範圍: 有符號: -2147483648 ~ 2147483647 無符號: ~ 4294967295 ======================================== bigint[(m)][unsigned][zerofill] 大整數,數據類型用於保存一些範圍的整數數值範圍: 有符號: -9223372036854775808 ~ 9223372036854775807 無符號: ~ 18446744073709551615
驗證1 : 有符號和無符號 tinyintide
============有符號tinyint============== # 建立數據庫db4 create database db4 charset utf8; # 切換到當前db4數據庫 mysql> use db4; # 建立t1 規定x字段爲tinyint數據類型(默認是有符號的) mysql> create table t1(x tinyint); # 驗證,插入-1這個數 mysql> insert into t1 values(-1); # 查詢 表記錄,查詢成功(證實默認是有符號類型) mysql> select * from t1; +------+ | x | +------+ | -1 | +------+ #執行以下操做,會發現報錯。由於有符號範圍在(-128,127) mysql> insert into t1 values(-129),(128); ERROR 1264 (22003): Out of range value for column 'x' at row 1 ============無符號tinyint============== # 建立表時定義記錄的字符爲無符號類型(0,255) ,使用unsigned mysql> create table t2(x tinyint unsigned); # 報錯,超出範圍 mysql> insert into t2 values(-129); ERROR 1264 (22003): Out of range value for column 'x' at row 1 # 插入成功 mysql> insert into t2 values(255); Query OK, 1 row affected (0.00 sec)
驗證2 : int 類型後面的存儲是顯示寬度,而不是存儲寬度函數
mysql> create table t3(id int(1) unsigned); #插入255555記錄也是能夠的 mysql> insert into t3 values(255555); mysql> select * from t3; +--------+ | id | +--------+ | 255555 | +--------+ ps:以上操做還不可以驗證,再來一張表驗證用zerofill 用0填充 # zerofill 用0填充 mysql> create table t4(id int(5) unsigned zerofill); mysql> insert into t4 value(1); Query OK, 1 row affected (0.00 sec) #插入的記錄是1,可是顯示的寬度是00001 mysql> select * from t4; +-------+ | id | +-------+ | 00001 | +-------+ row in set (0.00 sec)
注意:爲該類型指定寬度時,僅僅只是指定查詢結果的顯示寬度,與存儲範圍無關,存儲範圍以下post
其實咱們徹底不必爲整數類型指定顯示寬度,使用默認的就能夠了性能
默認的顯示寬度,都是在最大值的基礎上加1優化
int的存儲寬度是4個Bytes,即32個bit,即2**32
無符號最大值爲:4294967296-1
有符號最大值:2147483648-1
有符號和無符號的最大數字須要的顯示寬度均爲10,而針對有符號的最小值則須要11位才能顯示徹底,因此int類型默認的顯示寬度爲11是很是合理的
最後:整形類型,其實沒有必要指定顯示寬度,使用默認的就ok.
二 . 浮點型
定點數類型: dec 等同於 declmal
浮點類型:float double
做用:存儲薪資、身高、體重、體質參數等
語法:
-------------------------FLOAT------------------- FLOAT[(M,D)] [UNSIGNED] [ZEROFILL] #參數解釋:單精度浮點數(非準確小數值),M是全長,D是小數點後個數。M最大值爲255,D最大值爲30 #有符號: -3.402823466E+38 to -1.175494351E-38, 1.175494351E-38 to 3.402823466E+38 #無符號: 1.175494351E-38 to 3.402823466E+38 #精確度: **** 隨着小數的增多,精度變得不許確 **** -------------------------DOUBLE----------------------- DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL] #參數解釋: 雙精度浮點數(非準確小數值),M是全長,D是小數點後個數。M最大值爲255,D最大值爲30 #有符號: -1.7976931348623157E+308 to -2.2250738585072014E-308 2.2250738585072014E-308 to 1.7976931348623157E+308 #無符號: 2.2250738585072014E-308 to 1.7976931348623157E+308 #精確度: ****隨着小數的增多,精度比float要高,但也會變得不許確 **** ====================================== --------------------DECIMAL------------------------ decimal[(m[,d])] [unsigned] [zerofill] #參數解釋:準確的小數值,M是整數部分總個數(負號不算),D是小數點後個數。 M最大值爲65,D最大值爲30。 #精確度: **** 隨着小數的增多,精度始終準確 **** 對於精確數值計算時須要用此類型 decaimal可以存儲精確值的緣由在於其內部按照字符串存儲。
驗證三種類型建表 :
#1驗證FLOAT類型建表: mysql> create table t5(x float(256,31)); ERROR 1425 (42000): Too big scale 31 specified for column 'x'. Maximum is 30. mysql> create table t5(x float(256,30)); ERROR 1439 (42000): Display width out of range for column 'x' (max = 255) mysql> create table t5(x float(255,30)); #建表成功 Query OK, 0 rows affected (0.03 sec) #2驗證DOUBLE類型建表: mysql> create table t6(x double(255,30)); #建表成功 Query OK, 0 rows affected (0.03 sec) #3驗證deimal類型建表: mysql> create table t7(x decimal(66,31)); ERROR 1425 (42000): Too big scale 31 specified for column 'x'. Maximum is 30. mysql> create table t7(x decimal(66,30)); ERROR 1426 (42000): Too big precision 66 specified for column 'x'. Maximum is 65. mysql> create table t7(x decimal(65,30)); #建表成功 Query OK, 0 rows affected (0.00 sec)
驗證三種類型的精度 :
# 分別對三張表插入相應的記錄 mysql> insert into t5 values(1.1111111111111111111111111111111);#小數點後31個1 Query OK, 1 row affected (0.01 sec) mysql> insert into t6 values(1.1111111111111111111111111111111); Query OK, 1 row affected (0.01 sec) mysql> insert into t7 values(1.1111111111111111111111111111111); Query OK, 1 row affected, 1 warning (0.00 sec) # 查詢結果 mysql> select * from t5; #隨着小數的增多,精度開始不許確 +----------------------------------+ | x | +----------------------------------+ | 1.111111164093017600000000000000 | +----------------------------------+ 1 row in set (0.00 sec) mysql> select * from t6; #精度比float要準確點,但隨着小數的增多,一樣變得不許確 +----------------------------------+ | x | +----------------------------------+ | 1.111111111111111200000000000000 | +----------------------------------+ 1 row in set (0.00 sec) mysql> select * from t7; #精度始終準確,d爲30,因而只留了30位小數 +----------------------------------+ | x | +----------------------------------+ | 1.111111111111111111111111111111 | +----------------------------------+ 1 row in set (0.00 sec)
總結 :
小數 : float : 在爲數比較短的狀況下不精確 double : 在爲數比較長的狀況下不精確 0.000001230123123123 存成:0.000001230000 decimal : 精確 , 內部原理是以字符串形式去存.#(推薦)
三 . 日期類型
date , time , datetime , timestamp , year .
做用 : 存儲用戶註冊時間,文章發佈時間 , 員工入職時間,出生時間 , 過時時間等.
語法: YEAR YYYY(1901/2155) DATE YYYY-MM-DD(1000-01-01/9999-12-31) TIME HH:MM:SS('-838:59:59'/'838:59:59') DATETIME YYYY-MM-DD HH:MM:SS(1000-01-01 00:00:00/9999-12-31 23:59:59 Y) TIMESTAMP YYYYMMDD HHMMSS(1970-01-01 00:00:00/2037 年某時)
驗證 :
1 . year
mysql> create table t8(born_year year);
#不管year指定何種寬度,最後都默認是year(4) Query OK, 0 rows affected (0.03 sec) #插入失敗,超出範圍(1901/2155) mysql> insert into t8 values -> (1900), -> (1901), -> (2155), -> (2156); ERROR 1264 (22003): Out of range value for column 'born_year' at row 1 mysql> select * from t8; Empty set (0.01 sec) mysql> insert into t8 values -> (1905), -> (2018); Query OK, 2 rows affected (0.00 sec) #插入記錄成功 Records: 2 Duplicates: 0 Warnings: 0 mysql> select * from t8; +-----------+ | born_year | +-----------+ | 1905 | | 2018 | +-----------+ 2 rows in set (0.00 sec)
2 . date , year , datetime (*****)
#建立t9表 mysql> create table t9(d date,t time,dt datetime); Query OK, 0 rows affected (0.06 sec) #查看錶的結構 mysql> desc t9; +-------+----------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+----------+------+-----+---------+-------+ | d | date | YES | | NULL | | | t | time | YES | | NULL | | | dt | datetime | YES | | NULL | | +-------+----------+------+-----+---------+-------+ 3 rows in set (0.14 sec) # 調用mysql自帶的now()函數,獲取當前類型指定的時間 以下結構 mysql> insert into t9 values(now(),now(),now()); Query OK, 1 row affected, 1 warning (0.01 sec) mysql> select * from t9; +------------+----------+---------------------+ | d | t | dt | +------------+----------+---------------------+ | 2018-06-09 | 09:35:20 | 2018-06-09 09:35:20 | +------------+----------+---------------------+ 1 row in set (0.00 sec)
3 . timestamp(瞭解)
mysql> create table t10(time timestamp); Query OK, 0 rows affected (0.06 sec) mysql> insert into t10 values(); Query OK, 1 row affected (0.00 sec) mysql> insert into t10 values(null); Query OK, 1 row affected (0.00 sec) mysql> select * from t10; +------+ | time | +------+ | NULL | | NULL | +------+ mysql> insert into t10 values(now()); Query OK, 1 row affected (0.01 sec) mysql> select * from t10; +---------------------+ | time | +---------------------+ | 2018-06-09 09:44:48 | +---------------------+ 1 row in set (0.01 sec)
datatime 和 timestamp 的區別


在實際應用的不少場景中,MySQL的這兩種日期類型都可以知足咱們的須要,存儲精度都爲秒,但在某些狀況下,會展示出他們各自的優劣。 下面就來總結一下兩種日期類型的區別。 1.DATETIME的日期範圍是1001——9999年,TIMESTAMP的時間範圍是1970——2038年。 2.DATETIME存儲時間與時區無關,TIMESTAMP存儲時間與時區有關,顯示的值也依賴於時區。在mysql服務器, 操做系統以及客戶端鏈接都有時區的設置。 3.DATETIME使用8字節的存儲空間,TIMESTAMP的存儲空間爲4字節。所以,TIMESTAMP比DATETIME的空間利用率更高。 4.DATETIME的默認值爲null;TIMESTAMP的字段默認不爲空(not null),默認值爲當前時間(CURRENT_TIMESTAMP), 若是不作特殊處理,而且update語句中沒有指定該列的更新值,則默認更新爲當前時間。
注意事項 :


============注意啦,注意啦,注意啦=========== #1. 單獨插入時間時,須要以字符串的形式,按照對應的格式插入 #2. 插入年份時,儘可能使用4位值 #3. 插入兩位年份時,<=69,以20開頭,好比50, 結果2050 >=70,以19開頭,好比71,結果1971 create table t12(y year); insert into t12 values (50),(71); select * from t12; +------+ | y | +------+ | 2050 | | 1971 | +------+
練習 :
建立一張學生表(student),有id ,姓名 , 出生年份 , 出生的年月日 , 上學時間 , 和到學校的具體時間.
mysql> create table student( -> id int, -> name varchar(20), -> born_year year, -> birth date, -> class_time time, -> reg_time datetime -> ); Query OK, 0 rows affected (0.02 sec) mysql> insert into student values -> (1,'alex',"1995","1995-11-11","11:11:11","2017-11-11 11:11:11"), -> (2,'egon',"1997","1997-12-12","12:12:12","2017-12-12 12:12:12"), -> (3,'wsb',"1998","1998-01-01","13:13:13","2017-01-01 13:13:13"); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> select * from student; +------+------+-----------+------------+------------+---------------------+ | id | name | born_year | birth | class_time | reg_time | +------+------+-----------+------------+------------+---------------------+ | 1 | alex | 1995 | 1995-11-11 | 11:11:11 | 2017-11-11 11:11:11 | | 2 | egon | 1997 | 1997-12-12 | 12:12:12 | 2017-12-12 12:12:12 | | 3 | wsb | 1998 | 1998-01-01 | 13:13:13 | 2017-01-01 13:13:13 | +------+------+-----------+------------+------------+---------------------+ rows in set (0.00 sec)
四 . 字符類型
官網 : https://dev.mysql.com/doc/refman/5.7/en/char.html
#注意:char和varchar括號內的參數指的都是字符的長度 #char類型:定長,簡單粗暴,浪費空間,存取速度快 字符長度範圍:0-255(一箇中文是一個字符,是utf8編碼的3個字節) 存儲: 存儲char類型的值時,會往右填充空格來知足長度 例如:指定長度爲10,存>10個字符則報錯,存<10個字符則用空格填充直到湊夠10個字符存儲 檢索: 在檢索或者說查詢時,查出的結果會自動刪除尾部的空格,除非咱們打開pad_char_to_full_length SQL模式(設置SQL模式:SET sql_mode = 'PAD_CHAR_TO_FULL_LENGTH'; 查詢sql的默認模式:select @@sql_mode;) #varchar類型:變長,精準,節省空間,存取速度慢 字符長度範圍:0-65535(若是大於21845會提示用其餘類型 。mysql行最大限制爲65535字節,字符編碼爲utf-8:https://dev.mysql.com/doc/refman/5.7/en/column-count-limit.html) 存儲: varchar類型存儲數據的真實內容,不會用空格填充,若是'ab ',尾部的空格也會被存起來 強調:varchar類型會在真實數據前加1-2Bytes的前綴,該前綴用來表示真實數據的bytes字節數(1-2Bytes最大表示65535個數字,正好符合mysql對row的最大字節限制,即已經足夠使用) 若是真實的數據<255bytes則須要1Bytes的前綴(1Bytes=8bit 2**8最大表示的數字爲255) 若是真實的數據>255bytes則須要2Bytes的前綴(2Bytes=16bit 2**16最大表示的數字爲65535) 檢索: 尾部有空格會保存下來,在檢索或者說查詢時,也會正常顯示包含空格在內的內容
官網解釋以下 :
注意 : 兩個函數
length(); #查看字節數 char_length(); #查看字符數
char 填充空格來知足固定長度,可是在查詢的時候卻會將尾部的空格刪除(裝做本身沒有浪費空間同樣). 可是能夠經過修改 sql_mode 讓其現原形.
# 建立t1表,分別指明字段x爲char類型,字段y爲varchar類型 mysql> create table t1(x char(5),y varchar(4)); Query OK, 0 rows affected (0.16 sec) # char存放的是5個字符,而varchar存4個字符 mysql> insert into t1 values('你瞅啥 ','你瞅啥 '); Query OK, 1 row affected (0.01 sec) # 在檢索時char很不要臉地將本身浪費的2個字符給刪掉了,裝的好像本身沒浪費過空間同樣,而varchar很老實,存了多少,就顯示多少 mysql> select x,char_length(x),y,char_length(y) from t1; +-----------+----------------+------------+----------------+ | x | char_length(x) | y | char_length(y) | +-----------+----------------+------------+----------------+ | 你瞅啥 | 3 | 你瞅啥 | 4 | +-----------+----------------+------------+----------------+ row in set (0.02 sec) #略施小計,讓char現原形 mysql> SET sql_mode = 'PAD_CHAR_TO_FULL_LENGTH'; Query OK, 0 rows affected (0.00 sec) #查看當前mysql的mode模式 mysql> select @@sql_mode; +-------------------------+ | @@sql_mode | +-------------------------+ | PAD_CHAR_TO_FULL_LENGTH | +-------------------------+ row in set (0.00 sec) #原形畢露了吧。。。。 mysql> select x,char_length(x) y,char_length(y) from t1; +-------------+------+----------------+ | x | y | char_length(y) | +-------------+------+----------------+ | 你瞅啥 | 5 | 4 | +-------------+------+----------------+ row in set (0.00 sec) # 查看字節數 #char類型:3箇中文字符+2個空格=11Bytes #varchar類型:3箇中文字符+1個空格=10Bytes mysql> select x,length(x),y,length(y) from t1; +-------------+-----------+------------+-----------+ | x | length(x) | y | length(y) | +-------------+-----------+------------+-----------+ | 你瞅啥 | 11 | 你瞅啥 | 10 | +-------------+-----------+------------+-----------+ row in set (0.02 sec)
總結 :
字符串 : char(10) : 簡單粗暴 , 浪費空間,存取速度快 root 存成 root000000 varchar : 精確 , 節省空間 , 存取速度慢 sql 優化 : 建立表時, 定長的類型往前放 , 變長的日後放 >255個字符,超了就把文件路徑存放到數據庫中。 圖片,視頻等找一個文件服務器,數據庫中只存路徑或url。
整數 : tinyint , int , bigint 浮點型 : float , double , decimal 時間 : year , date , time , datetime 布爾類型 : boolean tinyint(1) #存1表示true , 存0表示false. 字符 : char 定長 > varchar 變長 > text 文本 #注意 : 雖然varchar使用起來比較靈活,可是從整個系統的性能角度來講,char 數據類型的處理速度更快 , text:text數據類型用於保存變長的大字符串,能夠組多到65535 (2**16 − 1)個字符。 mediumtext:A TEXT column with a maximum length of 16,777,215 (2**24 − 1) characters. longtext:A TEXT column with a maximum length of 4,294,967,295 or 4GB (2**32 − 1) characters.
五 . 枚舉類型和集合類型
字段的值只能在給定的範圍內選擇,如單選框,多選框
enum 單選, 只能在給定的範圍內選一個值,如性別 sex 男male / 女female
set 多選. 在給定的範圍內能夠選擇一個或者多個值,(愛好1,愛好2,愛好3......)
mysql> create table consumer( -> id int, -> name varchar(50), -> sex enum('male','female','other'), -> level enum('vip1','vip2','vip3','vip4'),#在指定範圍內,多選一 -> fav set('play','music','read','study') #在指定範圍內,多選多 -> ); Query OK, 0 rows affected (0.03 sec) mysql> insert into consumer values -> (1,'趙雲','male','vip2','read,study'), -> (2,'趙雲2','other','vip4','play'); Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> select * from consumer; +------+---------+-------+-------+------------+ | id | name | sex | level | fav | +------+---------+-------+-------+------------+ | 1 | 趙雲 | male | vip2 | read,study | | 2 | 趙雲2 | other | vip4 | play | +------+---------+-------+-------+------------+ rows in set (0.00 sec)
六 . 數據的增刪改查
增刪改
- 插入數據 insert
- 更新數據 update
- 刪除數據 delete
1、 在MySQL管理軟件中,能夠經過SQL語句中的DML語言來實現數據的操做,包括 1.使用INSERT實現數據的插入 2.UPDATE實現數據的更新 3.使用DELETE實現數據的刪除 4.使用SELECT查詢數據以及。 2、插入數據 INSERT 1. 插入完整數據(順序插入) 語法一: INSERT INTO 表名(字段1,字段2,字段3…字段n) VALUES(值1,值2,值3…值n); 語法二: INSERT INTO 表名 VALUES (值1,值2,值3…值n); 2. 指定字段插入數據 語法: INSERT INTO 表名(字段1,字段2,字段3…) VALUES (值1,值2,值3…); 3. 插入多條記錄 語法: INSERT INTO 表名 VALUES (值1,值2,值3…值n), (值1,值2,值3…值n), (值1,值2,值3…值n); 4. 插入查詢結果 語法: INSERT INTO 表名(字段1,字段2,字段3…字段n) SELECT (字段1,字段2,字段3…字段n) FROM 表2 WHERE …; 3、更新數據UPDATE 語法: UPDATE 表名 SET 字段1=值1, 字段2=值2, WHERE CONDITION; 示例: UPDATE mysql.user SET password=password(‘123’) where user=’root’ and host=’localhost’; 4、刪除數據DELETE 語法: DELETE FROM 表名 WHERE CONITION; 示例: DELETE FROM mysql.user WHERE password=’’;
查
單表查詢
語法 :
1、單表查詢的語法 SELECT 字段1,字段2... FROM 表名 WHERE #條件 GROUP BY field #分組查詢 HAVING # 篩選 ORDER BY field #查詢排序 LIMIT #限制條數 2、關鍵字的執行優先級(重點) 重點中的重點:關鍵字的執行優先級 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.限制結果的顯示條數
建立公司員工表,表的字段和數據類型
company.employee 員工id id int 姓名 name varchar 性別 sex enum 年齡 age int 入職日期 hire_date date 崗位 post varchar 職位描述 post_comment varchar 薪水 salary double 辦公室 office int 部門編號 depart_id int


#建立表,設置字段的約束條件 create table employee( id int primary key 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; +--------------+-----------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+-----------------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | emp_name | varchar(20) | NO | | NULL | | | sex | enum('male','female') | NO | | male | | | age | int(3) unsigned | NO | | 28 | | | hire_date | date | NO | | NULL | | | post | varchar(50) | YES | | NULL | | | post_comment | varchar(100) | YES | | NULL | | | salart | double(15,2) | YES | | NULL | | | office | int(11) | YES | | NULL | | | depart_id | int(11) | YES | | NULL | | +--------------+-----------------------+------+-----+---------+----------------+ rows in set (0.08 sec) #插入記錄 #三個部門:教學,銷售,運營 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), ('xiaomage','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) ; 建立員工表,並插入記錄
(1) . where 約束
where子句中可使用 1.比較運算符:>、<、>=、<=、<>、!= 2.between 80 and 100 :值在80到100之間 3.in(80,90,100)值是10或20或30 4.like 'xiaomagepattern': pattern能夠是%或者_。%小時任意多字符,_表示一個字符 5.邏輯運算符:在多個條件直接可使用邏輯運算符 and or not
驗證 :


#1 :單條件查詢 mysql> select id,emp_name from employee where id > 5; +----+------------+ | id | emp_name | +----+------------+ | 6 | jingliyang | | 7 | jinxin | | 8 | xiaomage | | 9 | 歪歪 | | 10 | 丫丫 | | 11 | 丁丁 | | 12 | 星星 | | 13 | 格格 | | 14 | 張野 | | 15 | 程咬金 | | 16 | 程咬銀 | | 17 | 程咬銅 | | 18 | 程咬鐵 | #2 多條件查詢 mysql> select emp_name from employee where post='teacher' and salary>10000; +----------+ | emp_name | +----------+ | alex | | jinxin | +----------+ #3.關鍵字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; #注意''是空字符串,不是null SELECT name,post_comment FROM employee WHERE post_comment=''; ps: 執行 update employee set post_comment='' where id=2; 再用上條查看,就會有結果了 #5:關鍵字IN集合查詢 mysql> SELECT name,salary FROM employee WHERE salary=3000 OR salary=3500 OR salary=4000 OR salary=9000 ; +------------+---------+ | name | salary | +------------+---------+ | yuanhao | 3500.00 | | jingliyang | 9000.00 | +------------+---------+ rows in set (0.00 sec) mysql> SELECT name,salary FROM employee WHERE salary IN (3000,3500,4000,9000) ; +------------+---------+ | name | salary | +------------+---------+ | yuanhao | 3500.00 | | jingliyang | 9000.00 | +------------+---------+ mysql> SELECT name,salary FROM employee WHERE salary NOT IN (3000,3500,4000,9000) ; +-----------+------------+ | name | salary | +-----------+------------+ | egon | 7300.33 | | alex | 1000000.31 | | wupeiqi | 8300.00 | | liwenzhou | 2100.00 | | jinxin | 30000.00 | | xiaomage | 10000.00 | | 歪歪 | 3000.13 | | 丫丫 | 2000.35 | | 丁丁 | 1000.37 | | 星星 | 3000.29 | | 格格 | 4000.33 | | 張野 | 10000.13 | | 程咬金 | 20000.00 | | 程咬銀 | 19000.00 | | 程咬銅 | 18000.00 | | 程咬鐵 | 17000.00 | +-----------+------------+ rows in set (0.00 sec) #6:關鍵字LIKE模糊查詢 通配符’%’ mysql> SELECT * FROM employee WHERE name LIKE 'jin%'; +----+------------+--------+-----+------------+---------+--------------+----------+--------+-----------+ | id | name | sex | age | hire_date | post | post_comment | salary | office | depart_id | +----+------------+--------+-----+------------+---------+--------------+----------+--------+-----------+ | 6 | jingliyang | female | 18 | 2011-02-11 | teacher | NULL | 9000.00 | 401 | 1 | | 7 | jinxin | male | 18 | 1900-03-01 | teacher | NULL | 30000.00 | 401 | 1 | +----+------------+--------+-----+------------+---------+--------------+----------+--------+-----------+ rows in set (0.00 sec) 通配符'_' mysql> SELECT age FROM employee WHERE name LIKE 'ale_'; +-----+ | age | +-----+ | 78 | +-----+ row in set (0.00 sec) 練習: 1. 查看崗位是teacher的員工姓名、年齡 2. 查看崗位是teacher且年齡大於30歲的員工姓名、年齡 3. 查看崗位是teacher且薪資在9000-1000範圍內的員工姓名、年齡、薪資 4. 查看崗位描述不爲NULL的員工信息 5. 查看崗位是teacher且薪資是10000或9000或30000的員工姓名、年齡、薪資 6. 查看崗位是teacher且薪資不是10000或9000或30000的員工姓名、年齡、薪資 7. 查看崗位是teacher且名字是jin開頭的員工姓名、年薪 #對應的sql語句 select name,age from employee where post = 'teacher'; select name,age from employee where post='teacher' and age > 30; select name,age,salary from employee where post='teacher' and salary between 9000 and 10000; select * from employee where post_comment is not null; select name,age,salary from employee where post='teacher' and salary in (10000,9000,30000); select name,age,salary from employee where post='teacher' and salary not in (10000,9000,30000); select name,salary*12 from employee where post='teacher' and name like 'jin%'; where約束
(2) . group by 分組查詢
#一、首先明確一點:分組發生在where以後,即分組是基於where以後獲得的記錄而進行的 #二、分組指的是:將全部記錄按照某個相同字段進行歸類,好比針對員工信息表的職位分組,或者按照性別進行分組等 #三、爲什麼要分組呢? 取每一個部門的最高工資 取每一個部門的員工數 取男人數和女人數 小竅門:‘每’這個字後面的字段,就是咱們分組的依據 #四、大前提: 能夠按照任意字段分組,可是分組完畢後,好比group by post,只能查看post字段,若是想查看組內信息,須要藉助於聚合函數
當執行如下sql語句的時候,是以 post 字段查詢了組中的第一條數據,沒有任何意義,由於咱們如今想查出當前組的多條記錄.


mysql> select * from employee 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 | | 1000000.31 | 401 | 1 | | 1 | egon | male | 18 | 2017-03-01 | 駐沙河辦事處外交大使 | NULL | 7300.33 | 401 | 1 | +----+--------+--------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+ 4 rows in set (0.00 sec) #因爲沒有設置ONLY_FULL_GROUP_BY,因而也能夠有結果,默認都是組內的第一條記錄,但其實這是沒有意義的 若是想分組,則必需要設置全局的sql的模式爲ONLY_FULL_GROUP_BY mysql> set global sql_mode='ONLY_FULL_GROUP_BY'; Query OK, 0 rows affected (0.00 sec) #查看MySQL 5.7默認的sql_mode以下: mysql> select @@global.sql_mode; +--------------------+ | @@global.sql_mode | +--------------------+ | ONLY_FULL_GROUP_BY | +--------------------+ 1 row in set (0.00 sec) mysql> exit;#設置成功後,必定要退出,而後從新登陸方可生效 Bye
繼續驗證經過 group by 分組以後,只能查詢當前字段,若是想看組內信息,須要藉助聚合函數.
mysql> select * from emp group by post;# 報錯 ERROR 1054 (42S22): Unknown column 'post' in 'group statement' mysql> select post from employee group by post; +-----------------------------------------+ | post | +-----------------------------------------+ | operation | | sale | | teacher | | 駐沙河辦事處外交大使 | +-----------------------------------------+ 4 rows in set (0.00 sec)
(3) . 集合函數
max()求最大值 min()求最小值 avg()求平均值 sum() 求和 count() 求總個數 #強調:聚合函數聚合的是組的內容,如果沒有分組,則默認一組 # 每一個部門有多少個員工 select post,count(id) from employee group by post; # 每一個部門的最高薪水 select post,max(salary) from employee group by post; # 每一個部門的最低薪水 select post,min(salary) from employee group by post; # 每一個部門的平均薪水 select post,avg(salary) from employee group by post; # 每一個部門的全部薪水 select post,sum(age) from employee group by post;


1. 查詢崗位名以及崗位包含的全部員工名字 2. 查詢崗位名以及各崗位內包含的員工個數 3. 查詢公司內男員工和女員工的個數 4. 查詢崗位名以及各崗位的平均薪資 5. 查詢崗位名以及各崗位的最高薪資 6. 查詢崗位名以及各崗位的最低薪資 7. 查詢男員工與男員工的平均薪資,女員工與女員工的平均薪資
(4) . having 過濾
having 和 where 的區別 : #1 . 執行優先級從高到低 : where > group by > having #2 . where 發生在分組 group by 以前,於是 where 中能夠有任意字段,可是絕對不能使用聚合函數. #3 . having 發生在分組 group by 以後,於是 having 中可使用分組的字段,沒法直接取到其餘字段,可使用聚合函數.
驗證 :


驗證: mysql> select * from employee where salary>1000000; +----+------+------+-----+------------+---------+--------------+------------+--------+-----------+ | id | name | sex | age | hire_date | post | post_comment | salary | office | depart_id | +----+------+------+-----+------------+---------+--------------+------------+--------+-----------+ | 2 | alex | male | 78 | 2015-03-02 | teacher | | 1000000.31 | 401 | 1 | +----+------+------+-----+------------+---------+--------------+------------+--------+-----------+ 1 row in set (0.00 sec) mysql> select * from employee having salary>1000000; ERROR 1463 (42000): Non-grouping field 'salary' is used in HAVING clause # 必須使用group by才能使用group_concat()函數,將全部的name值鏈接 mysql> select post,group_concat(name) from emp group by post having salary > 10000; ##錯誤,分組後沒法直接取到salary字段 ERROR 1054 (42S22): Unknown column 'post' in 'field list'


#1. 查詢各崗位內包含的員工個數小於2的崗位名、崗位內包含員工名字、個數 #2. 查詢各崗位平均薪資大於10000的崗位名、平均工資 #3. 查詢各崗位平均薪資大於10000且小於20000的崗位名、平均工資 # 題1: mysql> select post,group_concat(name),count(id) from employee group by post; +-----------------------------------------+-----------------------------------------------------------+-----------+ | post | group_concat(name) | count(id) | +-----------------------------------------+-----------------------------------------------------------+-----------+ | operation | 程咬鐵,程咬銅,程咬銀,程咬金,張野 | 5 | | sale | 格格,星星,丁丁,丫丫,歪歪 | 5 | | teacher | xiaomage,jinxin,jingliyang,liwenzhou,yuanhao,wupeiqi,alex | 7 | | 老男孩駐沙河辦事處外交大使 | egon | 1 | +-----------------------------------------+-----------------------------------------------------------+-----------+ rows in set (0.00 sec) mysql> select post,group_concat(name),count(id) from employee group by post having count(id)<2; +-----------------------------------------+--------------------+-----------+ | post | group_concat(name) | count(id) | +-----------------------------------------+--------------------+-----------+ | 老男孩駐沙河辦事處外交大使 | egon | 1 | +-----------------------------------------+--------------------+-----------+ row in set (0.00 sec) #題2: mysql> select post,avg(salary) from employee group by post having avg(salary) > 10000; +-----------+---------------+ | post | avg(salary) | +-----------+---------------+ | operation | 16800.026000 | | teacher | 151842.901429 | +-----------+---------------+ rows in set (0.00 sec) #題3: mysql> select post,avg(salary) from employee group by post having avg(salary) > 10000 and avg(salary) <20000; +-----------+--------------+ | post | avg(salary) | +-----------+--------------+ | operation | 16800.026000 | +-----------+--------------+ row in set (0.00 sec)
(5) . order by 查詢排序
按單列排序 SELECT * FROM employee ORDER BY age; SELECT * FROM employee ORDER BY age ASC; SELECT * FROM employee ORDER BY age DESC; 按多列排序:先按照age升序排序,若是年紀相同,則按照id降序 SELECT * from employee ORDER BY age ASC, #asc 升序 id DESC; # desc 降序


驗證多列排序: SELECT * from employee ORDER BY age ASC,id DESC; mysql> SELECT * from employee ORDER BY age ASC,id DESC; +----+------------+--------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+ | id | name | sex | age | hire_date | post | post_comment | salary | office | depart_id | +----+------------+--------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+ | 18 | 程咬鐵 | female | 18 | 2014-05-12 | operation | NULL | 17000.00 | 403 | 3 | | 17 | 程咬銅 | male | 18 | 2015-04-11 | operation | NULL | 18000.00 | 403 | 3 | | 16 | 程咬銀 | female | 18 | 2013-03-11 | operation | NULL | 19000.00 | 403 | 3 | | 15 | 程咬金 | male | 18 | 1997-03-12 | operation | NULL | 20000.00 | 403 | 3 | | 12 | 星星 | female | 18 | 2016-05-13 | sale | NULL | 3000.29 | 402 | 2 | | 11 | 丁丁 | female | 18 | 2011-03-12 | sale | NULL | 1000.37 | 402 | 2 | | 7 | jinxin | male | 18 | 1900-03-01 | teacher | NULL | 30000.00 | 401 | 1 | | 6 | jingliyang | female | 18 | 2011-02-11 | teacher | NULL | 9000.00 | 401 | 1 | | 1 | egon | male | 18 | 2017-03-01 | 老男孩駐沙河辦事處外交大使 | NULL | 7300.33 | 401 | 1 | | 14 | 張野 | male | 28 | 2016-03-11 | operation | NULL | 10000.13 | 403 | 3 | | 13 | 格格 | female | 28 | 2017-01-27 | sale | NULL | 4000.33 | 402 | 2 | | 5 | liwenzhou | male | 28 | 2012-11-01 | teacher | NULL | 2100.00 | 401 | 1 | | 10 | 丫丫 | female | 38 | 2010-11-01 | sale | NULL | 2000.35 | 402 | 2 | | 9 | 歪歪 | female | 48 | 2015-03-11 | sale | NULL | 3000.13 | 402 | 2 | | 8 | xiaomage | male | 48 | 2010-11-11 | teacher | NULL | 10000.00 | 401 | 1 | | 4 | yuanhao | male | 73 | 2014-07-01 | teacher | NULL | 3500.00 | 401 | 1 | | 2 | alex | male | 78 | 2015-03-02 | teacher | | 1000000.31 | 401 | 1 | | 3 | wupeiqi | male | 81 | 2013-03-05 | teacher | NULL | 8300.00 | 401 | 1 | +----+------------+--------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+ rows in set (0.01 sec) mysql> 驗證多列排序


#1. 查詢全部員工信息,先按照age升序排序,若是age相同則按照hire_date降序排序 #2. 查詢各崗位平均薪資大於10000的崗位名、平均工資,結果按平均薪資升序排列 #3. 查詢各崗位平均薪資大於10000的崗位名、平均工資,結果按平均薪資降序排列 # 題目1 select * from employee ORDER BY age asc,hire_date desc; # 題目2 mysql> select post,avg(salary) from employee group by post having avg(salary) > 10000 order by avg(salary) asc; +-----------+---------------+ | post | avg(salary) | +-----------+---------------+ | operation | 16800.026000 | | teacher | 151842.901429 | +-----------+---------------+ rows in set (0.00 sec) # 題目3 mysql> select post,avg(salary) from employee group by post having avg(salary) > 10000 order by avg(salary) desc; +-----------+---------------+ | post | avg(salary) | +-----------+---------------+ | teacher | 151842.901429 | | operation | 16800.026000 | +-----------+---------------+ rows in set (0.00 sec) mysql> 小練習答案
(6) . 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條


# 第1頁數據 mysql> select * from employee limit 0,5; +----+-----------+------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+ | id | name | sex | age | hire_date | post | post_comment | salary | office | depart_id | +----+-----------+------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+ | 1 | egon | male | 18 | 2017-03-01 | 老男孩駐沙河辦事處外交大使 | NULL | 7300.33 | 401 | 1 | | 2 | alex | male | 78 | 2015-03-02 | teacher | | 1000000.31 | 401 | 1 | | 3 | wupeiqi | male | 81 | 2013-03-05 | teacher | NULL | 8300.00 | 401 | 1 | | 4 | yuanhao | male | 73 | 2014-07-01 | teacher | NULL | 3500.00 | 401 | 1 | | 5 | liwenzhou | male | 28 | 2012-11-01 | teacher | NULL | 2100.00 | 401 | 1 | +----+-----------+------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+ rows in set (0.00 sec) # 第2頁數據 mysql> select * from employee limit 5,5; +----+------------+--------+-----+------------+---------+--------------+----------+--------+-----------+ | id | name | sex | age | hire_date | post | post_comment | salary | office | depart_id | +----+------------+--------+-----+------------+---------+--------------+----------+--------+-----------+ | 6 | jingliyang | female | 18 | 2011-02-11 | teacher | NULL | 9000.00 | 401 | 1 | | 7 | jinxin | male | 18 | 1900-03-01 | teacher | NULL | 30000.00 | 401 | 1 | | 8 | xiaomage | male | 48 | 2010-11-11 | teacher | NULL | 10000.00 | 401 | 1 | | 9 | 歪歪 | female | 48 | 2015-03-11 | sale | NULL | 3000.13 | 402 | 2 | | 10 | 丫丫 | female | 38 | 2010-11-01 | sale | NULL | 2000.35 | 402 | 2 | +----+------------+--------+-----+------------+---------+--------------+----------+--------+-----------+ rows in set (0.00 sec) # 第3頁數據 mysql> select * from employee limit 10,5; +----+-----------+--------+-----+------------+-----------+--------------+----------+--------+-----------+ | id | name | sex | age | hire_date | post | post_comment | salary | office | depart_id | +----+-----------+--------+-----+------------+-----------+--------------+----------+--------+-----------+ | 11 | 丁丁 | female | 18 | 2011-03-12 | sale | NULL | 1000.37 | 402 | 2 | | 12 | 星星 | female | 18 | 2016-05-13 | sale | NULL | 3000.29 | 402 | 2 | | 13 | 格格 | female | 28 | 2017-01-27 | sale | NULL | 4000.33 | 402 | 2 | | 14 | 張野 | male | 28 | 2016-03-11 | operation | NULL | 10000.13 | 403 | 3 | | 15 | 程咬金 | male | 18 | 1997-03-12 | operation | NULL | 20000.00 | 403 | 3 | +----+-----------+--------+-----+------------+-----------+--------------+----------+--------+-----------+ rows in set (0.00 sec) 小練習答案
多表查詢
建立兩張表 , 部門表(department) , 員工表(employee).
#建立表 create table department( id int, name varchar(20) ); create table employee( id int primary key auto_increment, name varchar(20), sex enum('male','female') not null default 'male', age int, dep_id int ); #插入數據 insert into department values (200,'技術部門'), (201,'人力濟源'), (202,''銷售), (203,'運營'); insert into employee values(name,sex,age,dep_id ) values ('egon','male',18,200), ('alex','female',48,201), ('wupeiqi','male',38,201), ('yuanhao','female',28,202), ('nvshen','male',18,200), ('xiaomage','female',18,204); #查看錶結構和數據 # 查看錶結構和數據 mysql> desc department; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | | name | varchar(20) | YES | | NULL | | +-------+-------------+------+-----+---------+-------+ 2 rows in set (0.19 sec) mysql> desc employee; +--------+-----------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------+-----------------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(20) | YES | | NULL | | | sex | enum('male','female') | NO | | male | | | age | int(11) | YES | | NULL | | | dep_id | int(11) | YES | | NULL | | +--------+-----------------------+------+-----+---------+----------------+ 5 rows in set (0.01 sec) mysql> select * from department; +------+--------------+ | id | name | +------+--------------+ | 200 | 技術 | | 201 | 人力資源 | | 202 | 銷售 | | 203 | 運營 | +------+--------------+ 4 rows in set (0.02 sec) mysql> select * from employee; +----+----------+--------+------+--------+ | id | name | sex | age | dep_id | +----+----------+--------+------+--------+ | 1 | egon | male | 18 | 200 | | 2 | alex | female | 48 | 201 | | 3 | wupeiqi | male | 38 | 201 | | 4 | yuanhao | female | 28 | 202 | | 5 | nvshen | male | 18 | 200 | | 6 | xiaomage | female | 18 | 204 | +----+----------+--------+------+--------+ 6 rows in set (0.00 sec)
注意 : 在兩張表中,發現department 表中 id=203 部門在employee沒有對應的員工,發現 employee 中 id=6 的員工在 department 表中沒有對應的關係.
多表鏈接查詢
外連接語法 : ********
select 字段列表 from 表1 inner | left |right join 表2 on 表1.字段 = 表2.字段; # inner join 內連接 # left join 左連接 # right join 又連接
(1) . 交叉連接 : 不適用任何匹配條件(會生成 笛卡爾積--映射)


mysql> select * from employee,department; +----+----------+--------+------+--------+------+--------------+ | id | name | sex | age | dep_id | id | name | +----+----------+--------+------+--------+------+--------------+ | 1 | egon | male | 18 | 200 | 200 | 技術 | | 1 | egon | male | 18 | 200 | 201 | 人力資源 | | 1 | egon | male | 18 | 200 | 202 | 銷售 | | 1 | egon | male | 18 | 200 | 203 | 運營 | | 2 | alex | female | 48 | 201 | 200 | 技術 | | 2 | alex | female | 48 | 201 | 201 | 人力資源 | | 2 | alex | female | 48 | 201 | 202 | 銷售 | | 2 | alex | female | 48 | 201 | 203 | 運營 | | 3 | wupeiqi | male | 38 | 201 | 200 | 技術 | | 3 | wupeiqi | male | 38 | 201 | 201 | 人力資源 | | 3 | wupeiqi | male | 38 | 201 | 202 | 銷售 | | 3 | wupeiqi | male | 38 | 201 | 203 | 運營 | | 4 | yuanhao | female | 28 | 202 | 200 | 技術 | | 4 | yuanhao | female | 28 | 202 | 201 | 人力資源 | | 4 | yuanhao | female | 28 | 202 | 202 | 銷售 | | 4 | yuanhao | female | 28 | 202 | 203 | 運營 | | 5 | nvshen | male | 18 | 200 | 200 | 技術 | | 5 | nvshen | male | 18 | 200 | 201 | 人力資源 | | 5 | nvshen | male | 18 | 200 | 202 | 銷售 | | 5 | nvshen | male | 18 | 200 | 203 | 運營 | | 6 | xiaomage | female | 18 | 204 | 200 | 技術 | | 6 | xiaomage | female | 18 | 204 | 201 | 人力資源 | | 6 | xiaomage | female | 18 | 204 | 202 | 銷售 | | 6 | xiaomage | female | 18 | 204 | 203 | 運營 |
(2) . 內連接 : 只連接匹配的行
#找兩張表共有的部分,至關於利用條件從笛卡爾積結果中篩選出匹配的結果. #department 沒有 204 這個部門,於是employee 表中關於 204這條的員工信息沒有匹配出來 mysql> select employee.id,employee.name,employee.age,employee.sex,department.name from employee inner join department on employee.dep_id=department.id; +----+---------+------+--------+--------------+ | id | name | age | sex | name | +----+---------+------+--------+--------------+ | 1 | egon | 18 | male | 技術 | | 2 | alex | 48 | female | 人力資源 | | 3 | wupeiqi | 38 | male | 人力資源 | | 4 | yuanhao | 28 | female | 銷售 | | 5 | nvshen | 18 | male | 技術 | +----+---------+------+--------+--------------+ 5 rows in set (0.00 sec) #上述sql等同於 mysql> select employee.id,employee.name,employee.age,employee.sex,department.name from employee,department where employee.dep_id=department.id; #employee.id,employee.name,employee.age,employee.sex,department.name 至關於 *
(3) . 左連接 : 優先顯示左表的所有內容
#以左表爲準,即找出全部員工信息,固然包括沒有部門的員工 #本質就是:在內鏈接的基礎上增長左邊有,右邊沒有的結果 mysql> select employee.id,employee.name,department.name as depart_name from employee left join department on employee.dep_id=department.id; +----+----------+--------------+ | id | name | depart_name | +----+----------+--------------+ | 1 | egon | 技術 | | 5 | nvshen | 技術 | | 2 | alex | 人力資源 | | 3 | wupeiqi | 人力資源 | | 4 | yuanhao | 銷售 | | 6 | xiaomage | NULL | +----+----------+--------------+ 6 rows in set (0.00 sec)
(4) . 右連接 : 優先顯示右表的所有記錄
#以右表爲準,即找出全部部門信息,包括沒有員工的部門 #本質就是:在內鏈接的基礎上增長右邊有,左邊沒有的結果 mysql> select employee.id,employee.name,department.name as depart_name from employee right join department on employee.dep_id=department.id; +------+---------+--------------+ | id | name | depart_name | +------+---------+--------------+ | 1 | egon | 技術 | | 2 | alex | 人力資源 | | 3 | wupeiqi | 人力資源 | | 4 | yuanhao | 銷售 | | 5 | nvshen | 技術 | | NULL | NULL | 運營 | +------+---------+--------------+ 6 rows in set (0.00 sec)
(5) . 全外連接 : 顯示左右兩個表的所有記錄
#外鏈接:在內鏈接的基礎上增長左邊有右邊沒有的和右邊有左邊沒有的結果 #注意:mysql不支持全外鏈接 full JOIN #強調:mysql可使用此種方式間接實現全外鏈接 語法:select * from employee left join department on employee.dep_id = department.id union all select * from employee right join department on employee.dep_id = department.id; mysql> select * from employee left join department on employee.dep_id = department.id union select * from employee right join department on employee.dep_id = department.id ; +------+----------+--------+------+--------+------+--------------+ | id | name | sex | age | dep_id | id | name | +------+----------+--------+------+--------+------+--------------+ | 1 | egon | male | 18 | 200 | 200 | 技術 | | 5 | nvshen | male | 18 | 200 | 200 | 技術 | | 2 | alex | female | 48 | 201 | 201 | 人力資源 | | 3 | wupeiqi | male | 38 | 201 | 201 | 人力資源 | | 4 | yuanhao | female | 28 | 202 | 202 | 銷售 | | 6 | xiaomage | female | 18 | 204 | NULL | NULL | | NULL | NULL | NULL | NULL | NULL | 203 | 運營 | +------+----------+--------+------+--------+------+--------------+ 7 rows in set (0.01 sec) #注意 union與union all的區別:union會去掉相同的紀錄
總結 :


外連接 : 內連接 : 只連接匹配的行 select * from employee inner join department on employee.dep_id = department.id; 左連接 : 優先顯示左表中的記錄 select * from employee left join department on employee.dep_id = department.id; 右連接 : 優先顯示右表中的內容 select * from employee right join department on employee.dep_id = department.id; 全外連接 : select * from employee left join department on employee.dep_id = department.id union select * from employee right join department on employee.dep_id = department.id;
符合條件連接查詢
示例1 : 之內鏈接的方式查詢 employee 表和department表,而且 employee表中的age字段值必須大於25,即找出年齡大於25歲的員工以及員工所在的部門.
select employee.name,department.name from employee inner join department on employee.dep_di = department.id where arg > 25;
示例2 : 之內連接的方式查詢employee和department表,且以arg字段升序的方式顯示
#方法一 : select employee.id,employee.name,employee.age,department.name from employee inner join department on employee.dep_di = department.id where age > 25 order by age asc; #方法二 : 簡單點 select employee.id,employee.name,employee.age,department.name from employee,department where employee.dep_id = department.id and age > 25 order by age asc;
子查詢
#1 . 子查詢是將一個查詢語句嵌套在另外一個查詢語句中. #2 . 內層查詢語句的查詢結果,能夠爲外層查詢語句提供條件. #3 . 子查詢中能夠包含: in,not in , any , exists , not exists 等關鍵字. #4 . 還能夠包含比較運算符 : = , != ,> , < ......
(1) . 帶in關鍵字的子查詢
#查詢平均年齡在25歲以上的部門名 select id,name from department where id in (select dep_id from employee group by dep_id having avg(age) > 25); # 查看技術部員工姓名 select name from employee where dep_id in (select id from department where name='技術'); #查看不足1人的部門名 select name from department where id not in (select dep_id from employee group by dep_id); #先查詢人數,讓人數不屬於1
(2) . 帶比較運算符的子查詢
#比較運算符:=、!=、>、>=、<、<=、<> #查詢大於全部人平均年齡的員工名與年齡 mysql> select name,age from employee where age > (select avg(age) from employee); +---------+------+ | name | age | +---------+------+ | alex | 48 | | wupeiqi | 38 | +---------+------+ #查詢大於部門內平均年齡的員工名、年齡 思路: (1)先對員工表(employee)中的人員分組(group by),查詢出dep_id以及平均年齡。 (2)將查出的結果做爲臨時表,再對根據臨時表的dep_id和employee的dep_id做爲篩選條件將employee表和臨時表進行內鏈接。 (3)最後再將employee員工的年齡是大於平均年齡的員工名字和年齡篩選。 mysql> select t1.name,t1.age from employee as t1 inner join (select dep_id,avg(age) as avg_age from employee group by dep_id) as t2 on t1.dep_id = t2.dep_id where t1.age > t2.avg_age; +------+------+ | name | age | +------+------+ | alex | 48 |
(3) . 帶 exists 關鍵字的子查詢
#EXISTS關字鍵字表示存在。在使用EXISTS關鍵字時,內層查詢語句不返回查詢的記錄。而是返回一個真假值。True或False #當返回True時,外層查詢語句將進行查詢;當返回值爲False時,外層查詢語句不進行查詢 #department表中存在dept_id=203,Ture mysql> select * from employee where exists (select id from department where id=200); +----+----------+--------+------+--------+ | id | name | sex | age | dep_id | +----+----------+--------+------+--------+ | 1 | egon | male | 18 | 200 | | 2 | alex | female | 48 | 201 | | 3 | wupeiqi | male | 38 | 201 | | 4 | yuanhao | female | 28 | 202 | | 5 | nvshen | male | 18 | 200 | | 6 | xiaomage | female | 18 | 204 | +----+----------+--------+------+--------+ #department表中存在dept_id=205,False mysql> select * from employee where exists (select id from department where id=204); Empty set (0.00 sec)
練習 : 查詢每一個部門最新入職的員工
#建立表 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; +--------------+-----------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+-----------------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(20) | NO | | NULL | | | sex | enum('male','female') | NO | | male | | | age | int(3) unsigned | NO | | 28 | | | hire_date | date | NO | | NULL | | | post | varchar(50) | YES | | NULL | | | post_comment | varchar(100) | YES | | NULL | | | salary | double(15,2) | YES | | NULL | | | office | int(11) | YES | | NULL | | | depart_id | int(11) | YES | | NULL | | +--------------+-----------------------+------+-----+---------+----------------+ #插入記錄 #三個部門:教學,銷售,運營 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) ;
#答案 select * from employee as t1 inner join (select post,max(hire_date) as new_date from employee group by post) as t2 on t1.post=t2.post where t1.hire_date=t2.new_date;