MySQL的基本学习(三)——DD/M/QL三类SQL语言和SQLyog
MySQL的基本學習(三)——DD/M/QL三類SQL語言和SQLyog
?
前言
好久沒有學MySQL了,最近因為JavaWeb的原因,讓我正好在補習一下SQL語句等知識,SQL語句雖然在這系列的第一篇文章里聊過了,但是這篇文章里我計劃重新學一下
?
?
?
?
?
DDL
Data Definition Language,數(shù)據(jù)定義語言,用來定義數(shù)據(jù)庫對象
DDL主要用來操作數(shù)據(jù)庫和數(shù)據(jù)庫的表。
所謂操作,主要就是四個:CRUD
操作數(shù)據(jù)庫
R(Retrieve):查詢
- 查詢所有數(shù)據(jù)庫的名稱: SHOW DATABASES;
performance_schema、mysql、test(我刪了這個了)、information_schema 這四個數(shù)據(jù)庫是MySQL自帶的數(shù)據(jù)庫:
?
- 查詢創(chuàng)建數(shù)據(jù)庫的語法:SHOW CREATE DATABASE 庫名;
數(shù)據(jù)庫默認使用的是utf-8字符集。
?
C(Create):創(chuàng)建
- 創(chuàng)建數(shù)據(jù)庫:CREATE DATABASE 數(shù)據(jù)庫名;
- 創(chuàng)建數(shù)據(jù)庫:CREATE DATABASE IF NOT EXISTS 數(shù)據(jù)庫名;
這種創(chuàng)建數(shù)據(jù)庫與上面的區(qū)別在于:上面的創(chuàng)建語句,如果已經(jīng)存在同名數(shù)據(jù)庫,則會報錯;該語句,如果存在同名數(shù)據(jù)庫不會報錯,也不會去創(chuàng)建,如果沒有同名數(shù)據(jù)庫才會創(chuàng)建。
- 創(chuàng)建數(shù)據(jù)庫并指定字符集:CREATE DATABASE 數(shù)據(jù)庫名 CHARACTER SET 字符集;
“SHOW CREATE DATABASE 庫名” 查看數(shù)據(jù)庫字符集。
?
綜合利用:創(chuàng)建一個數(shù)據(jù)庫且指定字符集為utf-8,且有重名的話不能報錯。
CREATE DATABASE IF NOT EXISTS DB4 CHARACTER SET utf8;
?
U(Update):修改
- 修改數(shù)據(jù)庫字符集:ALTER DATABASE 數(shù)據(jù)庫名稱 CHARACTER SET 字符集;
?
D(Delete):刪除
- 刪除數(shù)據(jù)庫:DROP DATABASE 數(shù)據(jù)庫名稱;
- 刪除數(shù)據(jù)庫:DROP DATABASE IF EXISTS 數(shù)據(jù)庫名稱;
這種刪除數(shù)據(jù)庫與上面的區(qū)別在于:上面的刪除語句,如果沒有該數(shù)據(jù)庫,則會報錯;該語句,如果不存在該數(shù)據(jù)庫不會報錯,當然也不會去刪除,如果存在數(shù)據(jù)庫才會刪除。這個與CREATE那里的道理類似。
?
使用數(shù)據(jù)庫
- 查詢當前正在使用的數(shù)據(jù)庫的名稱:SELECT DATABASE();
- 使用數(shù)據(jù)庫:USE 數(shù)據(jù)庫名稱;
?
操作數(shù)據(jù)表
C(Create):創(chuàng)建
- 創(chuàng)建表:CREATE? TABLE? 表名? ( 列名1 數(shù)據(jù)類型1,列名2 數(shù)據(jù)類型2,列名3 數(shù)據(jù)類型3 );
常見數(shù)據(jù)庫數(shù)據(jù)類型:
注意,最后一個字段信息末尾不需要加逗號
- 復制一個數(shù)據(jù)表:CREATE? TABLE? 新表名? LIKE? 被復制表名
R(Retrieve):查詢
- 查詢某個數(shù)據(jù)庫中所有的表的名稱:SHOW TABLES;
- 查詢表結(jié)構(gòu):DESC 表名;
U(Update):修改
- 修改表名:ALTER? TABLE? 表名? RENAME? TO? 新表名;
- 修改表的字符集:ALTER? TABLE? student? CHARACTER? SET? utf8;
“SHOW CREATE TABLE student;”查看表以前的字符集
- 添加一個字段:ALTER? TABLE? 表名? ADD? 字段名? 數(shù)據(jù)類型;
- 修改字段名稱、類型:ALTER? TABLE? 表名? CHANGE? 字段? 新字段? 新字段數(shù)據(jù)類型;
- 修改字段類型:ALTER? TABLE? 表名? MODIFY? 字段名? 新數(shù)據(jù)類型
- 刪除字段:ALTER? TABLE? 表名? DROP? 字段名
?D(Delete):刪除
- 刪除數(shù)據(jù)表:DROP? TABLE? 表名;
- 刪除數(shù)據(jù)表:DROP? TABLE IF? EXISTS? 表名;
存在,則刪除、不存在,也不會報錯。
?
插曲:SQLyog
為了方便我們使用數(shù)據(jù)庫MySQL,這里我們來使用一個圖形化操作的工具SQLyog
分享鏈接:https://pan.baidu.com/s/1KJarOpABTpIR76yZGHOVTQ
提取碼:1d5u
一路下一步安裝即可
然后打開后會要求注冊序列號,sn.txt中隨便寫一個即可。
然后就可以成功打開了,然后會彈出一個連接到我的SQL主機,新建,配置用戶名、密碼,連接即可。
?配置新連接報錯:錯誤號碼?2058,分析是?mysql?密碼加密方法變了。
解決方式:先登錄你的數(shù)據(jù)庫,然后執(zhí)行
ALTER USER ‘root’@’localhost’ IDENTIFIED WITH mysql_native_password BY ‘password’;
password是你的登陸密碼。
正如workBench、Navicat等圖形化工具一樣,這類工具非常方便,很多操作可以直接點擊實現(xiàn),不需要輸入SQL語句,不過在我們學習階段,還是建議老老實實使用SQL語句去操作。
?
DML
Data Manipulation Language,數(shù)據(jù)操作語言,用來對數(shù)據(jù)庫中表的數(shù)據(jù)進行增刪改。
主要用來增刪表中的數(shù)據(jù),是非常重要的SQL語言。
DML主要是針對數(shù)據(jù)表中的數(shù)據(jù),這個主要分為三個方面:添加數(shù)據(jù)、刪除數(shù)據(jù)、修改數(shù)據(jù)
操作數(shù)據(jù)
添加數(shù)據(jù)
- 添加數(shù)據(jù):INSERT? INTO? 表名(字段1,字段2,……,字段n)? VALUES(值1,值2,……,值n);
注意點:
?
- 添加數(shù)據(jù):INSERT? INTO? 表名? VALUES(值1,值2,……,值n);
這條語句和上一句的區(qū)別在于:表名后面沒有說明字段,則給所有字段依次添加值,如果想要空開,可以使用“NULL”,如果對應字段數(shù)據(jù)類型是時間戳timestamp,則會自動填入當前時間。
刪除數(shù)據(jù)
- 刪除數(shù)據(jù):DELETE? FROM? 表名 [WHERE 條件]
注意:如果不添加條件,那么會將表中的記錄全部刪除!!!
- 刪除表,然后再創(chuàng)建一個一模一樣的空表:TRUNCATE? TABLE? 表名;
如果你想要刪除一個表中的所有記錄,建議使用TRUNBLE TABLE,而不是DELETE? FROM? 表名,因為后者會根據(jù)數(shù)據(jù)記錄數(shù)量執(zhí)行同等數(shù)量的指令,對性能不友好;而TRUNBLE TABLE,只會執(zhí)行“DROP”刪除表、“CREATE” 創(chuàng)建表,兩個指令,性能更佳。
老實說我不知道這個命令應該屬于DDL(數(shù)據(jù)定義語言),還是DML(數(shù)據(jù)操作語言)
修改數(shù)據(jù)
- UPDATE? 表名? SET? 列名1=值1,列名2=值2,……,列名n=值n? ?[WHERE? 條件];
注意:如果不添加任何條件,則會將表中所有記錄根據(jù)字段全部修改。
?
?
DQL
Data Query?Language,數(shù)據(jù)查詢語言,用來對數(shù)據(jù)庫中表的數(shù)據(jù)進行查詢。
?
基礎查詢
基本使用
查詢數(shù)據(jù):SELECT? *? FROM? 表名;
語法:
SELECT? ?字段列表
FROM? ?表名列表
[WHERE? 條件列表]
[GROUP? BY? 分組字段 ]
[HAVING? 分組之后的條件]
[ORDER? BY? 排序]
[LIMIT? 分頁限定]
mysql> select * from test; +----+-----------------+-----------+ | id | name | password | +----+-----------------+-----------+ | 1 | 可愛的兔子 | 123456 | | 2 | 兇惡的老虎 | 654321 | | 3 | 職工號 | 12345 | | 5 | 張無忌 | 987654321 | +----+-----------------+-----------+ 4 rows in set (0.00 sec) //查詢指定字段 mysql> SELECT name,sex FROM test; +--------+------+ | name | sex | +--------+------+ | 小紅 | 女 | | 小明 | 男 | | 小張 | 男 | | 小淺 | 女 | | 小軍 | 男 | | 小候 | 男 | | 阿煒 | 男 | | 小麗 | 女 | +--------+------+ 8 rows in set (0.00 sec)去重
查詢結(jié)果經(jīng)常會用來去重,例如男女、地名等,沒有必要顯示很多相同的。
語法:加入 DISTINCT 關鍵字
mysql> SELECT DISTINCT sex FROM test; +------+ | sex | +------+ | 女 | | 男 | +------+ 2 rows in set (0.00 sec)去重的話要保證結(jié)果集完全一樣,即多個字段完全一樣才能叫做重復。
計算
字段中直接設置一個“和字段”即可
mysql> SELECT name,math,english,math+english FROM test; +--------+------+---------+--------------+ | name | math | english | math+english | +--------+------+---------+--------------+ | 小王 | 56 | 57 | 113 | | 小李 | 85 | 78 | 163 | | 小趙 | 25 | 38 | 63 | +--------+------+---------+--------------+ 3 rows in set (0.00 sec)注意:如果有null,參與的運算,計算的結(jié)果都為null,如果不符合實際情況,可以結(jié)合函數(shù)IFNUll處理,例如上例加成績:SELECT name,math,english,math+IFNULL(english,0) FROM test;,即如果英語成績?yōu)镹ULL,則替換為0。
另外,對于字段 math+english,如果覺得難看,可以起一個別名,語法:SELECT name,math,english,math+english? AS? ?總分? ? FROM test; 即可,也可以省略AS關鍵字,其他字段math、english也可以這樣修改
mysql> SELECT name,math,english,math+english AS 總分 FROM test; +--------+------+---------+--------+ | name | math | english | 總分 | +--------+------+---------+--------+ | 小王 | 56 | 57 | 113 | | 小李 | 85 | 78 | 163 | | 小趙 | 25 | 38 | 63 | +--------+------+---------+--------+ 3 rows in set (0.00 sec)不過一般別名都會使用英文的。
?
條件查詢
語法: WHERE? ?條件
使用示例:
mysql> SELECT name,math FROM test WHERE math>=56; +--------+------+ | name | math | +--------+------+ | 小王 | 56 | | 小李 | 85 | +--------+------+ 2 rows in set (0.00 sec) //可以使用&&、AND,或者 BETWEEN AND mysql> SELECT name,math FROM test WHERE english BETWEEN 60 AND 100; +--------+------+ | name | math | +--------+------+ | 小李 | 85 | +--------+------+ 1 row in set (0.00 sec) mysql> SELECT * FROM test WHERE math IN(85,25); +----+--------+---------+------+ | id | name | english | math | +----+--------+---------+------+ | 2 | 小李 | 78 | 85 | | 3 | 小趙 | 38 | 25 | +----+--------+---------+------+ 2 rows in set (0.00 sec)?
?
常用SQL運算符:
| 比較運算符 | 說明 |
| >、<、<=、>=、=、<> | 其中,<>在SQL中表示不等于,在mysql中也可以使用!=,但是SQL中沒有==運算符 |
| BETWEEN…AND | 在一個范圍之內(nèi),如BETWEEN 100 AND 200,相當于條件在100到200之間,包頭且包尾 |
| IN(集合) | 集合表示多個值,使用逗號分隔 |
| LIKE ‘關鍵字’ | 模糊查詢 |
| IS NULL | 查詢某一列為NULL的值(不能寫 =NULL) |
| IS NOT NULL | 查詢某一列不為NULL的值 |
?
| 邏輯運算符 | 說明 |
| and 或 && | 與,SQL中建議使用前者,后者不通用 |
| or 或 || | 或 |
| not 或 ! | 非 |
?
模糊查詢
模糊查詢比較牛逼,我們單獨來說。
條件查詢中的模糊查詢使用關鍵字LIKE,需要注意的點:
- 占位符
- _:單個任意字符(一個)
- %:多個任意字符(0或者多個)
如果出現(xiàn)異常,可能是數(shù)據(jù)里存在空字符
?
排序查詢
語法:ORDER BY? 字句
具體使用:ORDER BY? 排序字段1? 排序方式1,排序字段2? 排序方式2,排序字段3? 排序方式3
單一排序條件
mysql> SELECT * FROM test ORDER BY id ASC; +----+--------+----------+ | id | name | password | +----+--------+----------+ | 1 | 喬峰 | 123 | | 2 | 段譽 | 234 | | 3 | 虛竹 | 345 | +----+--------+----------+ 3 rows in set (0.00 sec)mysql> SELECT * FROM test ORDER BY id DESC; +----+--------+----------+ | id | name | password | +----+--------+----------+ | 3 | 虛竹 | 345 | | 2 | 段譽 | 234 | | 1 | 喬峰 | 123 | +----+--------+----------+ 3 rows in set (0.00 sec)?排序方式:
學英語
ascend:上升、升高
descend:下降
多排序條件
如果第一排序條件相同,那么數(shù)據(jù)庫會根據(jù)第二排序條件進行排序,例如示例數(shù)學成績相同,根據(jù)英語成績升序排列:
mysql> SELECT * FROM score ORDER BY math ASC,english ASC; +------+-----------+------+---------+ | id | name | math | english | +------+-----------+------+---------+ | 3 | 郭富城 | 69 | 34 | | 2 | 劉德華 | 77 | 81 | | 1 | 張學友 | 77 | 85 | | 4 | 黎明 | 90 | 87 | +------+-----------+------+---------+ 4 rows in set (0.00 sec)?
聚合查詢
聚合函數(shù):將一列數(shù)據(jù)作為一個整體,然后進行縱向的計算
例如上例,計算四大天王的math的總成績,就可以使用聚合函數(shù)
可用聚合函數(shù):
語法:SELECT? 函數(shù)(字段)? ? FROM? 表名;
注意:聚合函數(shù)會排除NULL的數(shù)據(jù),解決方法可以利用IFNULL函數(shù),例如SELECT? COUNT(IFNULL(english,0))? FROM? student,即student表中的english字段中,將NULL替換成0,然后統(tǒng)計english字段下的個數(shù)。
mysql> SELECT AVG(math) FROM score; +-----------+ | AVG(math) | +-----------+ | 78.25 | +-----------+ 1 row in set (0.01 sec)?
分組查詢
分組查詢意為根據(jù)字段的值,將數(shù)據(jù)分組,然后根據(jù)分組進行處理。
語法:GROUP BY 分組字段
mysql> SELECT* FROM test; +----+--------+-------+------+ | id | name | score | sex | +----+--------+-------+------+ | 1 | 小紅 | 59 | 女 | | 2 | 小明 | 15 | 男 | | 3 | 小張 | 87 | 男 | | 4 | 小淺 | 79 | 女 | +----+--------+-------+------+ 4 rows in set (0.00 sec) //示例,將分數(shù)按照男女分組 mysql> SELECT sex,AVG(score) FROM test GROUP BY sex; +------+------------+ | sex | AVG(score) | +------+------------+ | 女 | 69.0000 | | 男 | 51.0000 | +------+------------+ 2 rows in set (0.01 sec)//進階示例:將分數(shù)按照男女分組,且不計入低于60分的同學 mysql> SELECT sex,AVG(score) FROM test WHERE score>60 GROUP BY sex; +------+------------+ | sex | AVG(score) | +------+------------+ | 男 | 87.0000 | | 女 | 79.0000 | +------+------------+ 2 rows in set (0.00 sec)//進階示例,分組后,顯示多于一個人的組的情況 mysql> SELECT sex,AVG(score) FROM test GROUP BY sex HAVING COUNT(id)>1; +------+------------+ | sex | AVG(score) | +------+------------+ | 女 | 69.0000 | | 男 | 51.0000 | +------+------------+ 2 rows in set (0.00 sec)注意:
?
補充,對于HAVING的使用可以采用“別名”的機制來使命令簡潔:
//給聚合函數(shù)COUNT(id)起一個別名,在后面HAVING后面可以直接使用別名代替 mysql> SELECT sex,COUNT(id) num FROM test GROUP BY sex HAVING num>1; +------+-----+ | sex | num | +------+-----+ | 女 | 2 | | 男 | 2 | +------+-----+ 2 rows in set (0.00 sec)分頁查詢
語法:LIMIT 開始的索引,每頁查詢的條數(shù);
mysql> SELECT * FROM test; +----+--------+-------+------+ | id | name | score | sex | +----+--------+-------+------+ | 1 | 小紅 | 59 | 女 | | 2 | 小明 | 15 | 男 | | 3 | 小張 | 87 | 男 | | 4 | 小淺 | 79 | 女 | | 5 | 小軍 | 68 | 男 | | 6 | 小候 | 77 | 男 | | 7 | 阿煒 | 59 | 男 | | 8 | 小麗 | 63 | 女 | +----+--------+-------+------+ 8 rows in set (0.00 sec)mysql> SELECT * FROM test LIMIT 0,3; +----+--------+-------+------+ | id | name | score | sex | +----+--------+-------+------+ | 1 | 小紅 | 59 | 女 | | 2 | 小明 | 15 | 男 | | 3 | 小張 | 87 | 男 | +----+--------+-------+------+ 3 rows in set (0.00 sec)mysql> SELECT * FROM test LIMIT 3,3; +----+--------+-------+------+ | id | name | score | sex | +----+--------+-------+------+ | 4 | 小淺 | 79 | 女 | | 5 | 小軍 | 68 | 男 | | 6 | 小候 | 77 | 男 | +----+--------+-------+------+ 3 rows in set (0.00 sec)mysql> SELECT * FROM test LIMIT 6,3; +----+--------+-------+------+ | id | name | score | sex | +----+--------+-------+------+ | 7 | 阿煒 | 59 | 男 | | 8 | 小麗 | 63 | 女 | +----+--------+-------+------+ 2 rows in set (0.00 sec)公式:開始的索引=(當前的頁碼-1)*每頁顯示的條數(shù)
注意:
?
多表查詢(屬于DQL的知識點)
概述
基本語法:SELECT? 字段列表? FROM? 表名列表? WHERE? 條件
?
我們來造兩個表,跟著我做:
Dept:部門
CREATE TABLE dept(id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(20) );INSERT INTO dept (name) VALUES('開發(fā)部'), ('市場部'), ('財務部');emp:員工
CREATE TABLE emp( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(10), gender CHAR(1), salary DOUBLE, join_date DATE, dept_id INT, FOREIGN KEY (dept_id) REFERENCES dept(id) );INSERT INTO emp(name,gender,salary,join_date,dept_id) VALUES('孫悟空','男',7200,'2013-02-24',1);INSERT INTO emp(name,gender,salary,join_date,dept_id) VALUES('豬八戒','男',3600,'2012-07-04',2);INSERT INTO emp(name,gender,salary,join_date,dept_id) VALUES('唐僧','男',9000,'2015-01-29',2);INSERT INTO emp(name,gender,salary,join_date,dept_id) VALUES('白骨精','女',3000,'2010-04-20',3);INSERT INTO emp(name,gender,salary,join_date,dept_id) VALUES('蜘蛛精','女',6500,'2016-07-25',1);最終兩個表的內(nèi)容:
mysql> SELECT * FROM dept; +----+-----------+ | id | name | +----+-----------+ | 1 | 開發(fā)部 | | 2 | 市場部 | | 3 | 財務部 | +----+-----------+ 3 rows in set (0.00 sec)mysql> SELECT * FROM emp; +----+-----------+--------+--------+------------+---------+ | id | name | gender | salary | join_date | dept_id | +----+-----------+--------+--------+------------+---------+ | 1 | 孫悟空 | 男 | 7200 | 2013-02-24 | 1 | | 2 | 豬八戒 | 男 | 3600 | 2012-07-04 | 2 | | 3 | 唐僧 | 男 | 9000 | 2015-01-29 | 2 | | 4 | 白骨精 | 女 | 3000 | 2010-04-20 | 3 | | 5 | 蜘蛛精 | 女 | 6500 | 2016-07-25 | 1 | +----+-----------+--------+--------+------------+---------+ 5 rows in set (0.00 sec)操作示例
執(zhí)行語句SELECT? *? FROM? emp,dept
mysql> SELECT * FROM emp,dept; +----+-----------+--------+--------+------------+---------+----+-----------+ | id | name | gender | salary | join_date | dept_id | id | name | +----+-----------+--------+--------+------------+---------+----+-----------+ | 1 | 孫悟空 | 男 | 7200 | 2013-02-24 | 1 | 1 | 開發(fā)部 | | 1 | 孫悟空 | 男 | 7200 | 2013-02-24 | 1 | 2 | 市場部 | | 1 | 孫悟空 | 男 | 7200 | 2013-02-24 | 1 | 3 | 財務部 | | 2 | 豬八戒 | 男 | 3600 | 2012-07-04 | 2 | 1 | 開發(fā)部 | | 2 | 豬八戒 | 男 | 3600 | 2012-07-04 | 2 | 2 | 市場部 | | 2 | 豬八戒 | 男 | 3600 | 2012-07-04 | 2 | 3 | 財務部 | | 3 | 唐僧 | 男 | 9000 | 2015-01-29 | 2 | 1 | 開發(fā)部 | | 3 | 唐僧 | 男 | 9000 | 2015-01-29 | 2 | 2 | 市場部 | | 3 | 唐僧 | 男 | 9000 | 2015-01-29 | 2 | 3 | 財務部 | | 4 | 白骨精 | 女 | 3000 | 2010-04-20 | 3 | 1 | 開發(fā)部 | | 4 | 白骨精 | 女 | 3000 | 2010-04-20 | 3 | 2 | 市場部 | | 4 | 白骨精 | 女 | 3000 | 2010-04-20 | 3 | 3 | 財務部 | | 5 | 蜘蛛精 | 女 | 6500 | 2016-07-25 | 1 | 1 | 開發(fā)部 | | 5 | 蜘蛛精 | 女 | 6500 | 2016-07-25 | 1 | 2 | 市場部 | | 5 | 蜘蛛精 | 女 | 6500 | 2016-07-25 | 1 | 3 | 財務部 | +----+-----------+--------+--------+------------+---------+----+-----------+ 15 rows in set (0.00 sec)很牛逼,突然就有了這么多的數(shù)據(jù)。
其實這個結(jié)果集,有另外一個稱呼“笛卡爾積”,即有兩個集合A、B,A、B集合中所有成員的組合情況就稱為笛卡爾積。
上面的數(shù)據(jù)中,我們的emp表中的dept_id 屬性代表該員工所屬哪個部門,這個值應該與dept表中的id相同才有必要顯示,換句話說就是,我們需要消除不必要的查詢數(shù)據(jù)。
這就需要我們進行多表查詢的分類,從而消除無用數(shù)據(jù):
?
多表查詢的分類
內(nèi)連接查詢
- 隱式內(nèi)連接:使用WHERE條件來消除無用的數(shù)據(jù)
以上例為例,我們要查詢所有員工的信息和對應部門的信息:
mysql> SELECT * FROM emp,dept WHERE emp.`dept_id`=dept.`id`; +----+-----------+--------+--------+------------+---------+----+-----------+ | id | name | gender | salary | join_date | dept_id | id | name | +----+-----------+--------+--------+------------+---------+----+-----------+ | 1 | 孫悟空 | 男 | 7200 | 2013-02-24 | 1 | 1 | 開發(fā)部 | | 5 | 蜘蛛精 | 女 | 6500 | 2016-07-25 | 1 | 1 | 開發(fā)部 | | 2 | 豬八戒 | 男 | 3600 | 2012-07-04 | 2 | 2 | 市場部 | | 3 | 唐僧 | 男 | 9000 | 2015-01-29 | 2 | 2 | 市場部 | | 4 | 白骨精 | 女 | 3000 | 2010-04-20 | 3 | 3 | 財務部 | +----+-----------+--------+--------+------------+---------+----+-----------+ 5 rows in set (0.00 sec)注意:在WHERE后面使用“表名.`字段`”來指出參與比較的字段,字段左右是反單引號,不是單引號,不過其實加不加都可以。
如果我們只是想要得到幾個字段的內(nèi)容,也需要指出字段所屬哪個表:
mysql> SELECT emp.`name`,emp.`gender`,dept.`name` FROM emp,dept WHERE emp.dept_id=dept.id; +-----------+--------+-----------+ | name | gender | name | +-----------+--------+-----------+ | 孫悟空 | 男 | 開發(fā)部 | | 蜘蛛精 | 女 | 開發(fā)部 | | 豬八戒 | 男 | 市場部 | | 唐僧 | 男 | 市場部 | | 白骨精 | 女 | 財務部 | +-----------+--------+-----------+ 5 rows in set (0.00 sec)重復輸好幾次表名不免有些繁瑣,所以一般我們來進行多表的處理的話,會給表起個別名,并且在寫的時候要注意分行,方便我們以后加注釋等操作。
mysql> SELECT-> t1.name,-> t1.gender,-> t2.name -- 部門的名稱-> FROM-> emp t1,-> dept t2-> WHERE-> t1.`dept_id` = t2.`id`; +-----------+--------+-----------+ | name | gender | name | +-----------+--------+-----------+ | 孫悟空 | 男 | 開發(fā)部 | | 蜘蛛精 | 女 | 開發(fā)部 | | 豬八戒 | 男 | 市場部 | | 唐僧 | 男 | 市場部 | | 白骨精 | 女 | 財務部 | +-----------+--------+-----------+ 5 rows in set (0.00 sec)?
- 顯式內(nèi)連接:基本語法–? SELECT? 字段列表? FROM? 表名? [INNER] JOIN? 表名2? ON? 條件
內(nèi)連接顯式查詢中,INNER這個關鍵字是可以省略的。
總結(jié): 內(nèi)連接顯式查詢的是兩表其交集的部分(是否交集由條件ON判斷)
- 內(nèi)連接查詢注意事項:
- 從哪些表中查詢數(shù)據(jù)
- 查詢條件是什么
- 查詢哪些字段
?
外連接查詢
- 左外連接:語法– SELECT? 字段列表? FROM? 表1? LEFT? [OUTER]? JOIN? 表2? ON? 條件
我們在之前例子的基礎上升級,給emp表添加一個新員工——小白龍,因為剛?cè)肼?#xff0c;所以他沒有部門。
+----+-----------+--------+--------+------------+---------+ | id | name | gender | salary | join_date | dept_id | +----+-----------+--------+--------+------------+---------+ | 1 | 孫悟空 | 男 | 7200 | 2013-02-24 | 1 | | 2 | 豬八戒 | 男 | 3600 | 2012-07-04 | 2 | | 3 | 唐僧 | 男 | 9000 | 2015-01-29 | 2 | | 4 | 白骨精 | 女 | 3000 | 2010-04-20 | 3 | | 5 | 蜘蛛精 | 女 | 6500 | 2016-07-25 | 1 | | 6 | 小白龍 | 男 | 3000 | NULL | NULL | +----+-----------+--------+--------+------------+---------+ 6 rows in set (0.00 sec)需求:查詢所有員工信息,如果員工有所屬部門,則查詢部門的名稱;沒有部門則不顯示部門的名稱。
//使用內(nèi)連接隱式查詢,結(jié)果沒有“小白龍”,不符合需求 mysql> SELECT-> t1.*,-> t2.`name`-> FROM-> emp t1,-> dept t2-> WHERE-> t1.`dept_id` = t2.`id`; +----+-----------+--------+--------+------------+---------+-----------+ | id | name | gender | salary | join_date | dept_id | name | +----+-----------+--------+--------+------------+---------+-----------+ | 1 | 孫悟空 | 男 | 7200 | 2013-02-24 | 1 | 開發(fā)部 | | 5 | 蜘蛛精 | 女 | 6500 | 2016-07-25 | 1 | 開發(fā)部 | | 2 | 豬八戒 | 男 | 3600 | 2012-07-04 | 2 | 市場部 | | 3 | 唐僧 | 男 | 9000 | 2015-01-29 | 2 | 市場部 | | 4 | 白骨精 | 女 | 3000 | 2010-04-20 | 3 | 財務部 | +----+-----------+--------+--------+------------+---------+-----------+ 5 rows in set (0.01 sec)使用內(nèi)連接隱式查詢,結(jié)果沒有“小白龍”,不符合需求,因為小白龍的dept_id值是NULL,自然不會有匹配的id值。
接下來我們使用左外連接查詢:
mysql> SELECT-> t1.*,-> t2.`name`-> FROM-> emp t1-> LEFT OUTER JOIN-> dept t2-> ON-> t1.`dept_id` = t2.`id`; +----+-----------+--------+--------+------------+---------+-----------+ | id | name | gender | salary | join_date | dept_id | name | +----+-----------+--------+--------+------------+---------+-----------+ | 1 | 孫悟空 | 男 | 7200 | 2013-02-24 | 1 | 開發(fā)部 | | 5 | 蜘蛛精 | 女 | 6500 | 2016-07-25 | 1 | 開發(fā)部 | | 2 | 豬八戒 | 男 | 3600 | 2012-07-04 | 2 | 市場部 | | 3 | 唐僧 | 男 | 9000 | 2015-01-29 | 2 | 市場部 | | 4 | 白骨精 | 女 | 3000 | 2010-04-20 | 3 | 財務部 | | 6 | 小白龍 | 男 | 3000 | NULL | NULL | NULL | +----+-----------+--------+--------+------------+---------+-----------+ 6 rows in set (0.01 sec)總結(jié):左外連接查詢的是左表所有數(shù)據(jù)以及其交集的部分。
?
- 右外連接:語法– SELECT? 字段列表? FROM? 表1? RIGHT? [OUTER]? JOIN? 表2? ON? 條件
結(jié)論:右外連接查詢的是右表所有數(shù)據(jù)以及其交集的部分。
mysql> SELECT-> t1.*,-> t2.`name`-> FROM-> emp t1-> RIGHT OUTER JOIN-> dept t2-> ON-> t1.`dept_id` = t2.`id`; +------+-----------+--------+--------+------------+---------+-----------+ | id | name | gender | salary | join_date | dept_id | name | +------+-----------+--------+--------+------------+---------+-----------+ | 1 | 孫悟空 | 男 | 7200 | 2013-02-24 | 1 | 開發(fā)部 | | 5 | 蜘蛛精 | 女 | 6500 | 2016-07-25 | 1 | 開發(fā)部 | | 2 | 豬八戒 | 男 | 3600 | 2012-07-04 | 2 | 市場部 | | 3 | 唐僧 | 男 | 9000 | 2015-01-29 | 2 | 市場部 | | 4 | 白骨精 | 女 | 3000 | 2010-04-20 | 3 | 財務部 | +------+-----------+--------+--------+------------+---------+-----------+ 5 rows in set (0.00 sec)“小白龍”消失了,因為“小白龍”既不是右表(dept)的內(nèi)容,也不是兩表的交集(不滿足ON后面的條件),所以沒有查詢出來。
?
子查詢
概念:子查詢就是在查詢中嵌套查詢,稱嵌套查詢?yōu)樽硬樵儭?/p>
以上例繼續(xù),我們來查詢最高工資的員工。
mysql> SELECT-> *-> FROM-> emp t1-> WHERE-> t1.`salary` = (-> SELECT-> MAX(salary)-> FROM-> emp-> ); +----+--------+--------+--------+------------+---------+ | id | name | gender | salary | join_date | dept_id | +----+--------+--------+--------+------------+---------+ | 3 | 唐僧 | 男 | 9000 | 2015-01-29 | 2 | +----+--------+--------+--------+------------+---------+ 1 row in set (0.01 sec)語句并不難理解,其實就是查詢中嵌套查詢,子查詢的結(jié)果作為查詢條件繼續(xù)查詢。
子查詢的難點在于存在不同的情況,我們下面來依次介紹:
- 子查詢的結(jié)果是單行單列的:
該情況下,子查詢可以作為一個條件,使用運算符去判斷。
再看個示例,查看員工中工資小于平均工資的人:
mysql> SELECT-> *-> FROM-> emp t1-> WHERE-> t1.`salary` < (-> SELECT-> AVG(salary)-> FROM-> emp-> ); +----+-----------+--------+--------+------------+---------+ | id | name | gender | salary | join_date | dept_id | +----+-----------+--------+--------+------------+---------+ | 2 | 豬八戒 | 男 | 3600 | 2012-07-04 | 2 | | 4 | 白骨精 | 女 | 3000 | 2010-04-20 | 3 | | 6 | 小白龍 | 男 | 3000 | NULL | NULL | +----+-----------+--------+--------+------------+---------+ 3 rows in set (0.00 sec)注意,在子查詢中,不能使用總查詢中定義的別名。
?
- 子查詢的結(jié)果是多行單列的:
示例,查詢“財務部”和“市場部”所有的員工信息
查詢兩個部門,就要先獲得dept表中兩個部門各自的id,然后在emp表中符合id1或者id2的員工,這樣我們的子查詢得到的會是一個單列多行的結(jié)果,我們要怎么應用呢?看示例:
SELECT name,gender FROM emp WHERE dept_id IN ( SELECT id FROM dept WHERE NAME='財務部' OR NAME='市場部' );name gender --------- -------- 白骨精 女 豬八戒 男 唐僧 男?
- 子查詢的結(jié)果是多行多列的:
該情況下,子查詢不再可以作為WHERE后面的條件,而是可以作為一張?zhí)摂M表,再結(jié)合內(nèi)連接查詢等方法去查詢。
示例:查詢員工的入職日期是2013-11-11日之后的員工信息和部門信息。
SELECT * FROM dept t1,( SELECT * FROM emp WHERE emp.`join_date` > '2013-11-11' ) t2 -- 多行多列的大于規(guī)定日期的員工表 WHERE t1.`id`=t2.`dept_id`;id name id name gender salary join_date dept_id ------ --------- ------ --------- ------ ------ ---------- ---------2 市場部 3 唐僧 男 9000 2015-01-29 21 開發(fā)部 5 蜘蛛精 女 6500 2016-07-25 1即先從原始員工表中篩選出一張“日期大于‘2013-11-11’”的員工表,然后該升級員工表與部門表進行隱式內(nèi)連接查詢即可。
其實這個我們使用內(nèi)連接查詢也可以實現(xiàn):
SELECT * FROM emp t1, dept t2 WHERE t1.`dept_id` = t2.`id` AND t1.`join_date` > '2013-11-11';id name gender salary join_date dept_id id name ------ --------- ------ ------ ---------- ------- ------ -----------3 唐僧 男 9000 2015-01-29 2 2 市場部 5 蜘蛛精 女 6500 2016-07-25 1 1 開發(fā)部?
已經(jīng)寫了不少內(nèi)容了,我們把剩下的部分留給后面的文章
?
?
?
?
商業(yè)轉(zhuǎn)載 請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載 請標明出處,謝謝
?
?
?
?
?
總結(jié)
以上是生活随笔為你收集整理的MySQL的基本学习(三)——DD/M/QL三类SQL语言和SQLyog的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: poi下载模板含下拉框
- 下一篇: html中aspx的cs文件是css吗,