DML 操做是指對數據庫中表記錄的操做,主要包括表記錄的插入(insert)、更新(update)、刪除(delete)和查詢(select),是開發人員平常使用最頻繁的操做。mysql
表建立好後,就能夠往裏插入記錄了,插入記錄的基本語法以下sql
INSERT INTO tablename (field1, field2, .…, fieldn)VALUES (value1, value2, ..……, valuen);數據庫
向表 emp 中插入:ename 爲 zzx1,hiredate 爲 2000-01-01,sal 爲 2000,deptno 爲 1函數
mysql> desc emp; +----------+---------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------+---------------+------+-----+---------+-------+ | ename | varchar(10) | YES | | NULL | | | hiredate | date | YES | | NULL | | | sal | decimal(10,2) | YES | | NULL | | | deptno | int(2) | YES | | NULL | | +----------+---------------+------+-----+---------+-------+ 4 rows in set (0.01 sec) mysql> insert into emp(ename,hiredate,sal,deptno) values('zzx1','2000-01-01','2000',1); Query OK, 1 row affected (0.01 sec)
也能夠不用指定字段名稱,可是 values 後面的順序應該和字段的排列順序一致優化
mysql> insert into emp values('lisa','2003-02-01','3000',2); Query OK, 1 row affected (0.01 sec) mysql> insert into emp values('bjguan','2004-04-02','4000',1); Query OK, 1 row affected (0.01 sec)
只對表中的 ename 和 sal 字段顯式插入值code
mysql> insert into emp(ename,sal) values('dony',1000); Query OK, 1 row affected (0.01 sec)
查看實際插入的值排序
mysql> select * from emp; +--------+------------+---------+--------+ | ename | hiredate | sal | deptno | +--------+------------+---------+--------+ | zzx1 | 2000-01-01 | 2000.00 | 1 | | lisa | 2003-02-01 | 3000.00 | 2 | | bjguan | 2004-04-02 | 4000.00 | 1 | | dony | NULL | 1000.00 | NULL | +--------+------------+---------+--------+ 4 rows in set (0.00 sec)
能夠一次性插入多條記錄,每條記錄之間用逗號分隔ci
INSERT INTO tablename (field1, field2, ..…, fieldn)
VALUES
(record1_value1, record1_value2, .…, record1_valuen),
(record2_value1, record2_value2, .…, record2_valuen),
...
(recordn_value1, recordn_value2, .…, recordn_valuen);開發
首先建立表 deptit
mysql> create table dept(deptno int(2), deptname varchar(10)); Query OK, 0 rows affected (0.03 sec) mysql> desc dept; +----------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------+-------------+------+-----+---------+-------+ | deptno | int(2) | YES | | NULL | | | deptname | varchar(10) | YES | | NULL | | +----------+-------------+------+-----+---------+-------+ 2 rows in set (0.01 sec)
對 dept 表一次插入多條記錄
mysql> insert into dept values(1,'tech'),(2,'sale'),(5,'fin'),(5,'dept5'),(6,'dept6'); Query OK, 5 rows affected (0.01 sec) Records: 5 Duplicates: 0 Warnings: 0 mysql> select * from dept; +--------+----------+ | deptno | deptname | +--------+----------+ | 1 | tech | | 2 | sale | | 5 | fin | | 5 | dept5 | | 6 | dept6 | +--------+----------+ 5 rows in set (0.00 sec)
UPDATE tablename SET field1=value1, field2=value2, ..., fieldn=valuen [WHERE CONDITION]
將表 emp 中 ename 爲 「lisa」 的薪水(sal)從 3000 改成 4000
mysql> update emp set sal=4000 where ename='lisa'; Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from emp; +--------+------------+---------+--------+ | ename | hiredate | sal | deptno | +--------+------------+---------+--------+ | zzx1 | 2000-01-01 | 2000.00 | 1 | | lisa | 2003-02-01 | 4000.00 | 2 | | bjguan | 2004-04-02 | 4000.00 | 1 | | dony | NULL | 1000.00 | NULL | +--------+------------+---------+--------+ 4 rows in set (0.00 sec)
update 命令能夠同時更新多個表中的數據
UPDATE t1, t2, ..., tn set t1.field1=expr1, t2.field2=expr2, ..., tn.fieldn=exprn [WHERE CONDITION]
同時更新表 emp 中的字段 sal 和表 dept 中的字段 deptname
mysql> select * from emp; +--------+------------+---------+--------+ | ename | hiredate | sal | deptno | +--------+------------+---------+--------+ | zzx1 | 2000-01-01 | 100.00 | 1 | | lisa | 2003-02-01 | 200.00 | 2 | | bjguan | 2004-04-02 | 100.00 | 1 | | dony | 2005-02-05 | 2000.00 | 4 | +--------+------------+---------+--------+ 4 rows in set (0.00 sec) mysql> select * from dept; +--------+----------+ | deptno | deptname | +--------+----------+ | 1 | tech | | 2 | sale | | 5 | fin | +--------+----------+ 3 rows in set (0.00 sec) mysql> update emp a, dept b set a.sal=a.sal*b.deptno, b.deptname=a.ename where a.deptno=b.deptno; Query OK, 3 rows affected (0.01 sec) Rows matched: 5 Changed: 3 Warnings: 0 mysql> select * from emp; +--------+------------+---------+--------+ | ename | hiredate | sal | deptno | +--------+------------+---------+--------+ | zzx1 | 2000-01-01 | 100.00 | 1 | | lisa | 2003-02-01 | 400.00 | 2 | | bjguan | 2004-04-02 | 100.00 | 1 | | dony | 2005-02-05 | 2000.00 | 4 | +--------+------------+---------+--------+ 4 rows in set (0.00 sec) mysql> select * from dept; +--------+----------+ | deptno | deptname | +--------+----------+ | 1 | zzx1 | | 2 | lisa | | 5 | fin | +--------+----------+ 3 rows in set (0.00 sec)
DELETE FROM tablename [where CONDITION]
將 emp 中 ename 爲 「dony」 的記錄所有刪除
mysql> delete from emp where ename='dony'; Query OK, 1 row affected (0.01 sec) mysql> select * from emp; +--------+------------+--------+--------+ | ename | hiredate | sal | deptno | +--------+------------+--------+--------+ | zzx1 | 2000-01-01 | 100.00 | 1 | | lisa | 2003-02-01 | 400.00 | 2 | | bjguan | 2004-04-02 | 100.00 | 1 | +--------+------------+--------+--------+ 3 rows in set (0.00 sec)
能夠一次刪除多個表的數據
DELETE t1, t2, ..., tn FROM t1, t2, ..., tn [WHERE CONDITION]
若是 from 後面的表名用別名,則 delete 後面也要用相應的別名,不然會提示語法錯誤
同時刪除表 emp 和 dept 中 deptno 爲 3 的記錄
mysql> select * from emp; +--------+------------+---------+--------+ | ename | hiredate | sal | deptno | +--------+------------+---------+--------+ | zzx1 | 2000-01-01 | 100.00 | 1 | | lisa | 2003-02-01 | 200.00 | 2 | | bjguan | 2004-04-02 | 100.00 | 1 | | bzshen | 2005-04-01 | 300.00 | 3 | | dony | 2005-02-05 | 2000.00 | 4 | +--------+------------+---------+--------+ 5 rows in set (0.00 sec) mysql> select * from dept; +--------+----------+ | deptno | deptname | +--------+----------+ | 1 | tach | | 2 | sale | | 3 | hr | | 5 | fin | +--------+----------+ 4 rows in set (0.00 sec) mysql> delete a,b from emp a,dept b where a.deptno=b.deptno and a.deptno=3; Query OK, 2 rows affected (0.01 sec) mysql> select * from emp; +--------+------------+---------+--------+ | ename | hiredate | sal | deptno | +--------+------------+---------+--------+ | zzx1 | 2000-01-01 | 100.00 | 1 | | lisa | 2003-02-01 | 200.00 | 2 | | bjguan | 2004-04-02 | 100.00 | 1 | | dony | 2005-02-05 | 2000.00 | 4 | +--------+------------+---------+--------+ 4 rows in set (0.00 sec) mysql> select * from dept; +--------+----------+ | deptno | deptname | +--------+----------+ | 1 | tach | | 2 | sale | | 5 | fin | +--------+----------+ 3 rows in set (0.00 sec)
SELECT * FROM tablename [where CONDITION]
顯示 emp 表中的所有記錄
mysql> select * from emp; +--------+------------+---------+--------+ | ename | hiredate | sal | deptno | +--------+------------+---------+--------+ | zzx | 2000-01-01 | 2000.00 | 1 | | lisa | 2003-02-01 | 4000.00 | 2 | | bjguan | 2004-04-02 | 5000.00 | 1 | +--------+------------+---------+--------+ 3 rows in set (0.00 sec) mysql> select ename,hiredate,sal,deptno from emp; +--------+------------+---------+--------+ | ename | hiredate | sal | deptno | +--------+------------+---------+--------+ | zzx | 2000-01-01 | 2000.00 | 1 | | lisa | 2003-02-01 | 4000.00 | 2 | | bjguan | 2004-04-02 | 5000.00 | 1 | +--------+------------+---------+--------+ 3 rows in set (0.00 sec)
將表中的記錄去掉重複後顯示出來,能夠用distinct關鍵字來實現:
mysql> select ename,hiredate,sal,deptno from emp; +--------+------------+---------+--------+ | ename | hiredate | sal | deptno | +--------+------------+---------+--------+ | zzx | 2000-01-01 | 2000.00 | 1 | | lisa | 2003-02-01 | 4000.00 | 2 | | bjguan | 2004-04-02 | 5000.00 | 1 | +--------+------------+---------+--------+ 3 rows in set (0.00 sec) mysql> select distinct deptno from emp; +--------+ | deptno | +--------+ | 1 | | 2 | +--------+ 2 rows in set (0.00 sec)
查詢全部 deptno 爲 1 的記錄
mysql> select * from emp; +--------+------------+---------+--------+ | ename | hiredate | sal | deptno | +--------+------------+---------+--------+ | zzx | 2000-01-01 | 2000.00 | 1 | | lisa | 2003-02-01 | 4000.00 | 2 | | bjguan | 2004-04-02 | 5000.00 | 1 | +--------+------------+---------+--------+ 3 rows in set (0.00 sec) mysql> select * from emp where deptno=1; +--------+------------+---------+--------+ | ename | hiredate | sal | deptno | +--------+------------+---------+--------+ | zzx | 2000-01-01 | 2000.00 | 1 | | bjguan | 2004-04-02 | 5000.00 | 1 | +--------+------------+---------+--------+ 2 rows in set (0.00 sec)
多字段查詢
mysql> select * from emp where deptno=1 and sal<3000; +-------+------------+---------+--------+ | ename | hiredate | sal | deptno | +-------+------------+---------+--------+ | zzx | 2000-01-01 | 2000.00 | 1 | +-------+------------+---------+--------+ 1 row in set (0.00 sec)
SELECT * FROM tablename [WHERE CONDITION] [ORDER BY field1 [DESC | ASC], field2 [DESC | ASC], ..., fieldn [DESC | ASC]]
DESC:降序排列 ASC:升序排列
把 emp 表中的記錄按照工資高低進行顯示
mysql> select * from emp order by sal; +--------+------------+---------+--------+ | ename | hiredate | sal | deptno | +--------+------------+---------+--------+ | zzx | 2000-01-01 | 2000.00 | 1 | | dony | 2005-02-05 | 2000.00 | 4 | | lisa | 2003-02-01 | 4000.00 | 2 | | bjguan | 2004-04-02 | 5000.00 | 1 | +--------+------------+---------+--------+ 4 rows in set (0.00 sec)
若是排序字段的值同樣,則值相同的字段按照第二個排序字段進行排序,依次類推。若是隻有一個排序字段,則這些字段相同的記錄將會無序排列。
把 emp 表中的記錄按照部門編號 deptno 字段排序
mysql> select * from emp order by deptno; +--------+------------+---------+--------+ | ename | hiredate | sal | deptno | +--------+------------+---------+--------+ | zzx | 2000-01-01 | 2000.00 | 1 | | bjguan | 2004-04-02 | 5000.00 | 1 | | lisa | 2003-02-01 | 4000.00 | 2 | | dony | 2005-02-05 | 2000.00 | 4 | +--------+------------+---------+--------+ 4 rows in set (0.00 sec)
對於 deptno 相同的前兩條記錄,若是要按照工資由高到低排序,可使用如下命令
mysql> select * from emp order by deptno,sal desc; +--------+------------+---------+--------+ | ename | hiredate | sal | deptno | +--------+------------+---------+--------+ | bjguan | 2004-04-02 | 5000.00 | 1 | | zzx | 2000-01-01 | 2000.00 | 1 | | lisa | 2003-02-01 | 4000.00 | 2 | | dony | 2005-02-05 | 2000.00 | 4 | +--------+------------+---------+--------+ 4 rows in set (0.00 sec)
對於排序後的記錄,若是但願只顯示一部分,而不是所有,這時,就可使用 LIMIT 關鍵字來實現
SELECT ... [LIMIT offset_start, row_count]
其中 offset_start 表示記錄的起始偏移量,row_count 表示顯示的行數。
在默認狀況下,起始偏移量爲 0,只須要寫記錄行數就能夠,這時,實際顯示的就是前 n 條記錄。例如,顯示 emp 表中按照 sal 排序後的前 3 條記錄:
mysql> select * from emp order by sal limit 3; +-------+------------+---------+--------+ | ename | hiredate | sal | deptno | +-------+------------+---------+--------+ | zzx | 2000-01-01 | 2000.00 | 1 | | dony | 2005-02-05 | 2000.00 | 4 | | lisa | 2003-02-01 | 4000.00 | 2 | +-------+------------+---------+--------+ 3 rows in set (0.00 sec)
若是要顯示 emp 表中按照 sal 排序後從第二條記錄開始的 3 條記錄,可使用如下命令:
mysql> select * from emp order by sal limit 1,3; +--------+------------+---------+--------+ | ename | hiredate | sal | deptno | +--------+------------+---------+--------+ | dony | 2005-02-05 | 2000.00 | 4 | | lisa | 2003-02-01 | 4000.00 | 2 | | bjguan | 2004-04-02 | 5000.00 | 1 | +--------+------------+---------+--------+ 3 rows in set (0.00 sec)
SELECT [field1, field2, ..., fieldn] fun_name
FROM tablename
[WHERE where_contition]
[GROUP BY field1, field2, ..., fieldn
WITH ROLLUP]]
[HAVING where_contition]
參數說明:
sum(求和)
、count(記數)
、max(最大值)
、min(最小值)
、avg(平均值)
。注意:having 和 where 的區別在於,having 是對聚合後的結果進行條件的過濾,而 where 是在聚合前就對記錄進行過濾,若是邏輯容許,儘量用 where 先過濾記錄,這樣由於結果集減少,將對聚合的效率大大提升,最後再根據邏輯看是否用 having 進行再過濾。
在 emp 表中統計公司人數
mysql> select count(1) from emp; +----------+ | count(1) | +----------+ | 4 | +----------+ 1 row in set (0.00 sec)
在此基礎上,要統計各個部門的人數
mysql> select deptno,count(1) from emp group by deptno; +--------+----------+ | deptno | count(1) | +--------+----------+ | 1 | 2 | | 2 | 1 | | 4 | 1 | +--------+----------+ 3 rows in set (0.00 sec)
更詳細一些,既要統計部門人數,又要統計總人數
mysql> select deptno,count(1) from emp group by deptno with rollup; +--------+----------+ | deptno | count(1) | +--------+----------+ | 1 | 2 | | 2 | 1 | | 4 | 1 | | NULL | 4 | +--------+----------+ 4 rows in set (0.00 sec)
統計人數大於 1 的部門
mysql> select deptno,count(1) from emp group by deptno having count(1)>1; +--------+----------+ | deptno | count(1) | +--------+----------+ | 1 | 2 | +--------+----------+ 1 row in set (0.00 sec)
統計公司全部員工薪水總額、最高和最低薪水
mysql> select * from emp; +--------+------------+---------+--------+ | ename | hiredate | sal | deptno | +--------+------------+---------+--------+ | zzx | 2000-01-01 | 2000.00 | 1 | | lisa | 2003-02-01 | 4000.00 | 2 | | bjguan | 2004-04-02 | 5000.00 | 1 | | dony | 2005-02-05 | 2000.00 | 4 | +--------+------------+---------+--------+ 4 rows in set (0.00 sec) mysql> select sum(sal),max(sal),min(sal) from emp; +----------+----------+----------+ | sum(sal) | max(sal) | min(sal) | +----------+----------+----------+ | 13000.00 | 5000.00 | 2000.00 | +----------+----------+----------+ 1 row in set (0.00 sec)
當須要同時顯示多個表中的字段時,就能夠用錶鏈接來實現這樣的功能。從大類上分,錶鏈接分爲內鏈接和外鏈接,它們之間的最主要區別是,內鏈接僅選出兩張表中互相匹配的記錄,而外鏈接會選出其餘不匹配的記錄。經常使用的是內鏈接。
查詢出全部僱員的名字和所在部門名稱,由於僱員名稱和部門分別存放在表 emp 和 dept 中,所以,須要使用錶鏈接來進行查詢
mysql> select * from emp; +--------+------------+---------+--------+ | ename | hiredate | sal | deptno | +--------+------------+---------+--------+ | zzx | 2000-01-01 | 2000.00 | 1 | | lisa | 2003-02-01 | 4000.00 | 2 | | bjguan | 2004-04-02 | 5000.00 | 1 | | dony | 2005-02-05 | 2000.00 | 4 | +--------+------------+---------+--------+ 4 rows in set (0.00 sec) mysql> select * from dept; +--------+----------+ | deptno | deptname | +--------+----------+ | 1 | tach | | 2 | sale | | 5 | fin | +--------+----------+ 3 rows in set (0.01 sec) mysql> select ename,deptname from emp,dept where emp.deptno=dept.deptno; +--------+----------+ | ename | deptname | +--------+----------+ | zzx | tach | | bjguan | tach | | lisa | sale | +--------+----------+ 3 rows in set (0.00 sec)
外鏈接又分爲左鏈接和右鏈接:
查詢 emp 中全部用戶名和所在部門名稱
mysql> select * from emp; +--------+------------+---------+--------+ | ename | hiredate | sal | deptno | +--------+------------+---------+--------+ | zzx | 2000-01-01 | 2000.00 | 1 | | lisa | 2003-02-01 | 4000.00 | 2 | | bjguan | 2004-04-02 | 5000.00 | 1 | | dony | 2005-02-05 | 2000.00 | 4 | +--------+------------+---------+--------+ 4 rows in set (0.00 sec) mysql> select * from dept; +--------+----------+ | deptno | deptname | +--------+----------+ | 1 | tach | | 2 | sale | | 5 | fin | +--------+----------+ 3 rows in set (0.00 sec) mysql> select ename,deptname from emp left join dept on emp.deptno=dept.deptno; +--------+----------+ | ename | deptname | +--------+----------+ | zzx | tach | | bjguan | tach | | lisa | sale | | dony | NULL | +--------+----------+ 4 rows in set (0.00 sec)
右鏈接和左鏈接相似,二者之間能夠互相轉化,上面的例子能夠改寫爲以下的右鏈接
mysql> select ename,deptname from dept right join emp on dept.deptno=emp.deptno; +--------+----------+ | ename | deptname | +--------+----------+ | zzx | tach | | bjguan | tach | | lisa | sale | | dony | NULL | +--------+----------+ 4 rows in set (0.00 sec)
某些狀況下,當進行查詢的時候,須要的條件是另一個 select 語句的結果,這個時候,就要用到子查詢。用於子查詢的關鍵字主要包括 in
、not in
、=
、!=
、exists
、not exists
等。
從 emp 表中查詢出全部部門在 dept 表中的全部記錄
mysql> select * from emp -> where deptno -> in(select deptno from dept); +--------+------------+---------+--------+ | ename | hiredate | sal | deptno | +--------+------------+---------+--------+ | zzx | 2000-01-01 | 2000.00 | 1 | | bjguan | 2004-04-02 | 5000.00 | 1 | | lisa | 2003-02-01 | 4000.00 | 2 | +--------+------------+---------+--------+ 3 rows in set (0.00 sec)
若是子查詢記錄數惟一,還能夠用 = 代替 in
mysql> select * from emp -> where deptno = (select deptno from dept); ERROR 1242 (21000): Subquery returns more than 1 row mysql> select * from emp -> where deptno = (select deptno from dept limit 1); +--------+------------+---------+--------+ | ename | hiredate | sal | deptno | +--------+------------+---------+--------+ | zzx | 2000-01-01 | 2000.00 | 1 | | bjguan | 2004-04-02 | 5000.00 | 1 | +--------+------------+---------+--------+ 2 rows in set (0.00 sec)
某些狀況下,子查詢能夠轉化爲錶鏈接
mysql> select * from emp where deptno in(select deptno from dept); +--------+------------+---------+--------+ | ename | hiredate | sal | deptno | +--------+------------+---------+--------+ | zzx | 2000-01-01 | 2000.00 | 1 | | bjguan | 2004-04-02 | 5000.00 | 1 | | lisa | 2003-02-01 | 4000.00 | 2 | +--------+------------+---------+--------+ 3 rows in set (0.00 sec) mysql> select emp.* from emp, dept where emp.deptno=dept.deptno; +--------+------------+---------+--------+ | ename | hiredate | sal | deptno | +--------+------------+---------+--------+ | zzx | 2000-01-01 | 2000.00 | 1 | | bjguan | 2004-04-02 | 5000.00 | 1 | | lisa | 2003-02-01 | 4000.00 | 2 | +--------+------------+---------+--------+ 3 rows in set (0.00 sec)
注意:子查詢和錶鏈接之間的轉換主要應用在兩個方面。
將兩個表的數據按照必定的查詢條件查詢出來後,將結果合併到一塊兒顯示出來,這個時候,就須要用 union
和 union all
關鍵字來實現這樣的功能
SELECT * FROM t1
UNION | UNION ALL
SELECT * FROM t2
...
UNION | UNION ALL
SELECT * FROM tn;
UNION 和 UNION ALL 的主要區別是 UNION ALL 是把結果集直接合並在一塊兒,而 UNION 是將 UNION ALL 後的結果進行一次 DISTINCT,去除重複記錄後的結果。
將 emp 和 dept 表中的部門編號的集合顯示出來
mysql> select * from emp; +--------+------------+---------+--------+ | ename | hiredate | sal | deptno | +--------+------------+---------+--------+ | zzx | 2000-01-01 | 2000.00 | 1 | | lisa | 2003-02-01 | 4000.00 | 2 | | bjguan | 2004-04-02 | 5000.00 | 1 | | dony | 2005-02-05 | 2000.00 | 4 | +--------+------------+---------+--------+ 4 rows in set (0.00 sec) mysql> select * from dept; +--------+----------+ | deptno | deptname | +--------+----------+ | 1 | tach | | 2 | sale | | 5 | fin | +--------+----------+ 3 rows in set (0.00 sec) mysql> select deptno from emp -> union all -> select deptno from dept; +--------+ | deptno | +--------+ | 1 | | 2 | | 1 | | 4 | | 1 | | 2 | | 5 | +--------+ 7 rows in set (0.00 sec)
將結果去掉重複記錄後顯示以下
mysql> select deptno from emp -> union -> select deptno from dept; +--------+ | deptno | +--------+ | 1 | | 2 | | 4 | | 5 | +--------+ 4 rows in set (0.00 sec)