數據類型

    介紹    

存儲引擎決定了表的類型,而表內存放的數據也要有不一樣的類型,每種數據類型都有本身的寬度,但寬度是可選的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
View Code

    

  驗證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語句中沒有指定該列的更新值,則默認更新爲當前時間。
View Code

     注意事項 : 

============注意啦,注意啦,注意啦===========
#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約束
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
View Code

      繼續驗證經過 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'
View Code
#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) 小練習答案
練習,分頁顯示,每頁5條

 

              多表查詢               

   建立兩張表 , 部門表(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 | 運營         |
View Code

 

  (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;
View Code

 

       符合條件連接查詢        

示例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;
相關文章
相關標籤/搜索