mysql 的crud操作(增刪改查)


1、mysql添加記錄

--添加記錄的語法(可添加單條記錄或者多條記錄),INTO是可以省略的,字段名也可以省略的,但是如果省略的話,后面對應的value的值就要全部填寫
INSERT [INTO] tab_name [(col_name,...)] {VALUE|VALUES} (values...);
--添加記錄的語法(只可添加一條記錄)
INSERT tab_name SET 字段名稱=字段值,...;
--從表中查詢記錄進行添加
INSERT tab_name SELECT 字段名稱 FROM tab1_name [WHERE 條件]

注意:通常情況下,以上語句在使用values插入單行數據的時候效率要比value來得高,但是插入多行數據的時候效率value要比values來得高,set與value|values相比效率要來得高,但是set是mysql的擴展,對於其他數據庫是不存在的,所以可移值性比較低,並且set一次只能添加一條數據。

 舉例:

--測試用表
CREATE TABLE IF NOT EXISTS test(
  id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT COMMENT '用戶ID',
  name VARCHAR(20) NOT NULL COMMENT '用戶名',
  sex ENUM('0','1','2') NOT NULL DEFAULT '0' COMMENT '性別0保密,1男,2女'
)ENGINE=INNODB CHARSET=UTF8;

--指定值
INSERT INTO test (name,sex) VALUES ('AA','0');
--不指定值,那么所對應的所有的值要全部寫出來
INSERT test VALUES (NULL,'BB','1');
--插入多條記錄,中間用逗號隔開,注意中英文狀下的逗號
INSERT test (name,sex) VALUE ('CC','2'),('DD','1'),('EE','0'),('FF','2');
--應用set來添加數據
INSERT test SET name="GG",sex="2";
--進行批量插入
INSERT user (name,sex) SELECT name,sex FROM test WHERE sex="1"

 2、修改記錄

--更改記錄的語法(有點類似INSERT..SET)
UPDATE tab_name SET 字段名=字段值,...[WHERE 條件];

注意:如果沒有指定where那么整張表的數據都會被更改。

--在id<3的名字后面加上ok,並且把性別改成默認值(默認值可以用DEFAULT來代替)
UPDATE test SET name=CONCAT(name,'ok'),sex=DEFAULT WHERE id<=3;
--SELECT * FROM test 輸出
-- +----+------+-----+
-- | id | name | sex |
-- +----+------+-----+
-- |  1 | AAok | 0   |
-- |  2 | BBok | 0   |
-- |  3 | CCok | 0   |
-- |  4 | DD   | 2   |
-- |  5 | EE   | 1   |
-- |  6 | FF   | 0   |
-- |  7 | GG   | 2   |
-- +----+------+-----+

批量更新數據表

使用MYSQL自帶語句進行批量更新

-- 使用update set 進行批量更新,注意:如果是多個條件的時候,每個條件的長度應該要相等
UPDATE tab_name SET 需修改的字段=CASE 參照字段 WHEN 參數字段值 THEN 修改字段值 ... END,...END [WHERE 條件];
-- 舉例,根據id修改名字和年齡
UPDATE user SET name = CASE id WHEN 1 THEN "AA" WHEN 2 THEN "BB" END,age=CASE id WHEN 1 THEN 18 WHEN 2 THEN 22 END WHERE id IN (1,2);

-- 查詢修改記錄,當查詢到目標記錄的時候進行修改,如果沒有查詢到則進行插入
INSERT INTO tab_name (字段名,...) VALUE (值,...) ON DUPLICATE KEY UPDATE 字段名=VALUES(字段名);
-- 舉例,注意:需要更改的字段放在ON DUPLICATE KEY UPDATE 后面
INSERT INTO `user` (id,name,age) VALUES (1,"小A",8),(2,"小B",18),(3,"小C",28),(4,"小D",38) ON DUPLICATE KEY UPDATE `name`=VALUES(name),age=VALUES(age);

--謹慎使用 使用replace into 進行批量更新,注意該操作本質是對重復的記錄先delete 后insert,如果更新的字段不全會將缺失的字段置為缺省值
REPLACE INTO tab_name (字段名,...) VALUE (值,...);
-- 舉例,如果在表中的唯一值里能匹配到相關的數據,那么會進行修改操作,否則會進行添加操作
REPLACE INTO user (id,name,age) VALUE (1,"CC",12),(2,"DD",27);

3、刪除記錄

--刪除記錄的語法,如果不添加條件,那么會刪除全部記錄
DELETE FROM tab_name [WHERE 條件];
--刪除記錄,同時也可以重置AUTO_INCREMENT的值
TRUNCATE [TABLE] tab_name

 注意:如果不添加條件,那么會刪除全部記錄,但是通過delete刪除的全部記錄,不會重置AUTO_INCREMENT的值,但是可以通過ALTER TABLE tab_name AUTO_INCREMENT=1 進行設置 

--刪除所有ID大於3的記錄
DELETE FROM test WHERE id>3;
--SELECT * FROM test 輸出
-- +----+------+-----+
-- | id | name | sex |
-- +----+------+-----+
-- |  1 | AAok | 0   |
-- |  2 | BBok | 0   |
-- |  3 | CCok | 0   |
-- +----+------+-----+

 4、查詢記錄

--查詢記錄的基本語法
SELECT select_expr,...FROM tab_name
[WHERE 條件]
[GROUP BY {col_name | position} HAVING 二次篩選]
[ORDER BY {col_name |position|expr} [ASC | DESC]]
[LIMIT 限制結果集的顯示條數]
[OFFSET 偏移量]
--可以使用庫名.表名的形式查詢數據(即可以不指定當前數據庫的情況下進行表查詢)
SELECT select_expr,...FROM db_name.tab_name

--可以給字段或者表名起別名(可以通過AS或者空隔對表名或者字段名進行起別名)
SELECT col_name AS col_rename,... FROM tab_name AS tab_rename
--建議要用AS來分隔,這個比較容易區分
SELECT col_name col_rename,... FROM tab_name tab_rename

注意:建議在起別名的時候,要加上AS以免引起混亂,並且在起別名的時候,要在字段上加上別名.字段,以免在以后在多表聯查時避免錯誤。

select distinct * from `表名`;

--以上面建的表為例
SELECT * FROM ytest.test;
-- 輸出
-- +----+------+-----+
-- | id | name | sex |
-- +----+------+-----+
-- |  1 | AAok | 0   |
-- |  2 | BBok | 0   |
-- |  3 | CCok | 0   |
-- +----+------+-----+

--給字段起別名
SELECT t.name AS text,t.sex AS ss FROM ytest.test AS t;
-- 輸出
-- +------+----+
-- | text | ss |
-- +------+----+
-- | AAok | 0  |
-- | BBok | 0  |
-- | CCok | 0  |
-- +------+----+

 distinct與sum,count一起使用

-- 原數組
-- +----+------+-------+-----+-------+
-- | id | name | score | sex | class |
-- +----+------+-------+-----+-------+
-- |  1 | aaa  |    80 | 女  | 二班  |
-- |  2 | bbb  |    30 | 男  | 二班  |
-- |  3 | ccc  |    40 | 女  | 二班  |
-- |  4 | ddd  |    50 | 男  | 一班  |
-- |  5 | eee  |    80 | 男  | 一班  |
-- |  6 | fff  |    70 | 女  | 一班  |
-- |  1 | aaa  |    80 | 女  | 二班  |
-- +----+------+-------+-----+-------+
SELECT SUM(DISTINCT `score`), COUNT(DISTINCT `score`) FROM `worker`;
-- 輸出
-- +-----------------------+-------------------------+
-- | SUM(DISTINCT `score`) | COUNT(DISTINCT `score`) |
-- +-----------------------+-------------------------+
-- | 270                   |                       5 |
-- +-----------------------+-------------------------+

5、WHERE 的條件篩選(WHERE 條件會查詢篩選出符合條件的記錄,如果沒有符合條件的記錄,那么就會返回空記錄)

a、where條件的比較運算符:=  >  >=  <  <=  !=  <>  <=>

--為原表添加一個字段
ALTER TABLE test ADD tDesc VARCHAR(30) COMMENT "描述";
--查詢id=2的記錄,其他用法也是一樣的
SELECT id,name,sex FROM test WHERE id=2;
--查詢是否為空值
SELECT id,name FROM test WHERE tDesc IS NULL;
SELECT id,name FROM test WHERE tDesc <=> NULL;
--查詢不為空值
SELECT id,name FROM test WHERE tDesc IS NOT NULL;

注意:<=>與=的用法基本一樣,但是<=>是可以檢測是否為NULL值,但是=不可以檢測,同時<=>是MYSQL獨有的語法,在其他語言不可以使用,而=可以通用

 b、邏輯運算符:AND(邏輯與)  OR(邏輯或)  NOT(邏輯非)   BETWEEN...AND...(介於兩者之間)

-- 舉例
SELECT id,name FROM test WHERE id<=2 AND sex='0';
-- 注意這個BETWEEN...AND...是包含1和2的
SELECT id,name FROM test WHERE id BETWEEN 1 AND 2;
-- NOT 舉例
SELECT id,name FROM test WHERE NOT (id = 1);

 c、模糊查詢like和 not like的使用

通配符%表示匹配0個1個或者多個字符,通配符_表示匹配一個字符

-- 匹配A前后有任意個字符的情況
SELECT id,name FROM test WHERE name LIKE "%A%";
-- 匹配A前有一個字付,后面任意個字符的情況
SELECT id,name FROM test WHERE name LIKE "_A%";
-- 匹配A前有一個字付,后面至少一個字符的情況
SELECT id,name FROM test WHERE name LIKE "_A_%";

 6、GROUP BY 分組

 group by 把值相同的放到一個組中,最終查詢出的結果只會顯示組中的一條記錄

--舉例
--的按照性別分組,group by 的值段可以沒有在SELECT 里面
SELECT id,name,sex FROM test GROUP BY sex;
--展示效果
-- +----+------+-----+
-- | id | name | sex |
-- +----+------+-----+
-- | 10 | CC   | 0   |
-- |  8 | AA   | 1   |
-- |  9 | BB   | 2   |
-- +----+------+-----+

注意,如果 需要看組中的成員,那么可以用到函數GROUP_CONCAT

--查看組中的成員
SELECT id,GROUP_CONCAT(name),GROUP_CONCAT(sex) FROM test Group BY sex;
--輸出
-- +----+--------------------+-------------------+
-- | id | GROUP_CONCAT(name) | GROUP_CONCAT(sex) |
-- +----+--------------------+-------------------+
-- | 10 | CC,EE              | 0,0               |
-- |  8 | AA,DD,GG           | 1,1,1             |
-- |  9 | BB,FF              | 2,2               |
-- +----+--------------------+-------------------+

 GROUP BY 配合聚合函數使用

COUNT() 計數   SUM()求和   MAX() 最大值   MIN()最小值    AVG() 平均值

COUNT(col_name)與COUNT(*)的最大區別是,前者如果遇到值為null的時候,則不會計入范圍,而后者會。所以后者可以作為統計總數用。

GROUP BY 與COUNT(*)結合的例子

--查看組中的成員,同時統計數量
SELECT sex,GROUP_CONCAT(name),COUNT(*) FROM test GROUP BY(sex);
--輸出
-- +-----+--------------------+----------+
-- | sex | GROUP_CONCAT(name) | COUNT(*) |
-- +-----+--------------------+----------+
-- | 0   | CC,EE              |        2 |
-- | 1   | AA,DD,GG           |        3 |
-- | 2   | BB,FF              |        2 |
-- +-----+--------------------+----------+

 GROUP BY 與SUM() ,  MAX() , MIN() , AVG() ,COUNT() 配合使用

--按性別分組,查看組中成員,個數,年齡總和,平均年齡,最小年齡,最大年齡
SELECT GROUP_CONCAT(name),COUNT(*),SUM(age),AVG(age),MAX(age),MIN(age) FROM test GROUP BY sex;
--輸出
-- +--------------------+----------+----------+----------+----------+----------+
-- | GROUP_CONCAT(name) | COUNT(*) | SUM(age) | AVG(age) | MAX(age) | MIN(age) |
-- +--------------------+----------+----------+----------+----------+----------+
-- | CC,EE              |        2 | 85       | 42.5000  |       47 |       38 |
-- | AA,DD,GG           |        3 | 103      | 34.3333  |       78 |        7 |
-- | BB,FF              |        2 | 48       | 24.0000  |       26 |       22 |
-- +--------------------+----------+----------+----------+----------+----------+

 

SELECT COUNT(IF(`score`>50,1,NULL)) FROM `worker`; -- 輸出
-- +------------------------------+
-- | COUNT(IF(`score`>50,1,NULL)) |
-- +------------------------------+
-- |                            2 |
-- +------------------------------+

 

sum 函數在對單列進行求和時如果有Null值,是不影響值,當對多列進行sum統計時,就會有錯誤。

注意:如果GROUP BY 在和WHERE 使用的時候,WHERE 應該要放在GROUP BY 前面,不然會報錯的。

--先查詢年齡大小20歲的並按性別分組,查看組中成員,個數,年齡總和,平均年齡,最小年齡,最大年齡
SELECT GROUP_CONCAT(name),COUNT(*),SUM(age),AVG(age),MAX(age),MIN(age) FROM test WHERE age>20 GROUP BY sex;
--輸出
-- +--------------------+----------+----------+----------+----------+----------+
-- | GROUP_CONCAT(name) | COUNT(*) | SUM(age) | AVG(age) | MAX(age) | MIN(age) |
-- +--------------------+----------+----------+----------+----------+----------+
-- | CC,EE              |        2 | 85       | 42.5000  |       47 |       38 |
-- | GG                 |        1 | 78       | 78.0000  |       78 |       78 |
-- | BB,FF              |        2 | 48       | 24.0000  |       26 |       22 |
-- +--------------------+----------+----------+----------+----------+----------+

 注意:如果對分組后的數據進行二次篩選,那么可以使用HAVING,並且HAVING要放在GROUP BY 后面,不然會報錯的,HAVING與WHERE的不同之處在於后者不能對AS后的字段不能選擇,而前者不能對未SELECT的字段進行選擇。

--按性別分組,查看組中成員,個數,年齡總和,平均年齡,最小年齡,最大年齡,並且篩選年齡總和大於50的組
SELECT GROUP_CONCAT(name),COUNT(*),SUM(age) AS total,AVG(age),MAX(age),MIN(age) FROM test GROUP BY sex HAVING total>50;
--輸出
-- +--------------------+----------+-------+----------+----------+----------+
-- | GROUP_CONCAT(name) | COUNT(*) | total | AVG(age) | MAX(age) | MIN(age) |
-- +--------------------+----------+-------+----------+----------+----------+
-- | CC,EE              |        2 | 85    | 42.5000  |       47 |       38 |
-- | AA,DD,GG           |        3 | 103   | 34.3333  |       78 |        7 |
-- +--------------------+----------+-------+----------+----------+----------+

在GROUP BY 后面 WITH ROLLUP 進行數據匯總,相當於把上面的值按一組情況進行統計

--按性別分組,查看組中成員,個數,年齡總和,平均年齡,最小年齡,最大年齡,並且進行全部數據的匯總
SELECT GROUP_CONCAT(name),COUNT(*),SUM(age),AVG(age),MAX(age),MIN(age) FROM test GROUP BY sex WITH ROLLUP;
--輸出
-- +----------------------+----------+----------+----------+----------+----------+
-- | GROUP_CONCAT(name)   | COUNT(*) | SUM(age) | AVG(age) | MAX(age) | MIN(age) |
-- +----------------------+----------+----------+----------+----------+----------+
-- | CC,EE                |        2 | 85       | 42.5000  |       47 |       38 |
-- | AA,DD,GG             |        3 | 103      | 34.3333  |       78 |       id 7 |
-- | BB,FF                |        2 | 48       | 24.0000  |       26 |       22 |
-- | CC,EE,AA,DD,GG,BB,FF |        7 | 236      | 33.7143  |       78 |        7 |
-- +----------------------+----------+----------+----------+----------+----------+

GROUP BY 也是可以進行多個分組統計的(中間用逗號隔開)

-- 數據源
+----+------+-------+-----+-------+
| id | name | score | sex | class |
+----+------+-------+-----+-------+
|  1 | aaa  |    80 || 二班  |
|  2 | bbb  |    30 || 二班  |
|  3 | ccc  |    40 || 二班  |
|  4 | ddd  |    50 || 一班  |
|  5 | eee  |    80 || 一班  |
+----+------+-------+-----+-------+
SELECT `sex`, `class`, AVG(`score`) FROM `worker` GROUP BY `sex`, `class`;
-- 輸出 
-- +-----+-------+------------+
-- | sex | class | avg(score) |
-- +-----+-------+------------+
-- | 男  | 一班  | 65.0000    |
-- | 男  | 二班  | 30.0000    |
-- | 女  | 二班  | 60.0000    |
-- +-----+-------+------------+
SELECT GROUP_CONCAT(`name`) AS "name",GROUP_CONCAT(`score`) AS "score",GROUP_CONCAT(`sex`) AS "sex",GROUP_CONCAT(`class`) AS "class",MAX(`score`),AVG(`score`) FROM `worker` GROUP BY `sex`,`class`;
-- 輸出
-- +---------+-------+-------+-----------+--------------+--------------+
-- | name    | score | sex   | class     | MAX(`score`) | AVG(`score`) |
-- +---------+-------+-------+-----------+--------------+--------------+
-- | ddd,eee | 50,80 | 男,男 | 一班,一班 |           80 | 65.0000      |
-- | bbb     | 30    | 男    | 二班      |           30 | 30.0000      |
-- | aaa,ccc | 80,40 | 女,女 | 二班,二班 |           80 | 60.0000      |
-- +---------+-------+-------+-----------+--------------+--------------+

 7、ORDER BY 進行排序

 ORDER BY 對數據進行排序 語法:ORDER BY 字段名 ASC|DESC 默認是ASC 升序,DESC 降序,同時也可以按照多個字段排序(如果兩個字段相等的情況下)兩個排序有逗號隔開,如果按照隨機排序,那么用ORDER BY RAND() 即可

--按照年齡降序排序,如果有相同的情況下按照ID升序排序
SELECT * FROM test ORDER BY age DESC,id ASC;
-- 輸出
-- +----+------+-----+-----+
-- | id | name | sex | age |
-- +----+------+-----+-----+
-- | 14 | GG   | 1   |  78 |
-- | 12 | EE   | 0   |  47 |
-- | 10 | CC   | 0   |  38 |
-- | 13 | FF   | 2   |  26 |
-- |  9 | BB   | 2   |  22 |
-- |  8 | AA   | 1   |  18 |
-- | 11 | DD   | 1   |   7 |
-- +----+------+-----+-----+

-- 按照年齡隨機排序
SELECT * FROM test ORDER BY RAND();
-- 輸出
-- +----+------+-----+-----+
-- | id | name | sex | age |
-- +----+------+-----+-----+
-- |  8 | AA   | 1   |  18 |
-- | 14 | GG   | 1   |  78 |
-- | 10 | CC   | 0   |  38 |
-- | 11 | DD   | 1   |   7 |
-- |  9 | BB   | 2   |  22 |
-- | 12 | EE   | 0   |  47 |
-- | 13 | FF   | 2   |  26 |
-- +----+------+-----+-----+

 8、LIMIT , OFFSET 限制結果集顯示條數

 LIMIT+一個值 => 顯示結果集的前幾條數據;

LIMIT+offset+row_count=> 從offset開始,顯示row_count條數據

LIMIT +row_count OFFSET +offset => 意思同上(注意:offset要放在limit的后面,否則會報錯)  

--數據正常顯示
-- +----+------+-----+-----+
-- | id | name | sex | age |
-- +----+------+-----+-----+
-- |  8 | AA   | 1   |  18 |
-- |  9 | BB   | 2   |  22 |
-- | 10 | CC   | 0   |  38 |
-- | 11 | DD   | 1   |   7 |
-- | 12 | EE   | 0   |  47 |
-- | 13 | FF   | 2   |  26 |
-- | 14 | GG   | 1   |  78 |
-- +----+------+-----+-----+
--用LIMIT+數值
SELECT * FROM test ORDER BY id DESC LIMIT 3;
-- 輸出
-- +----+------+-----+-----+
-- | id | name | sex | age |
-- +----+------+-----+-----+
-- | 14 | GG   | 1   |  78 |
-- | 13 | FF   | 2   |  26 |
-- | 12 | EE   | 0   |  47 |
-- +----+------+-----+-----+

--用LIMIT+offset+row_count
SELECT * FROM test ORDER BY id LIMIT 3,2;
-- 輸出
-- +----+------+-----+-----+
-- | id | name | sex | age |
-- +----+------+-----+-----+
-- | 11 | DD   | 1   |   7 |
-- | 12 | EE   | 0   |  47 |
-- +----+------+-----+-----+

--利用LIMIT+row_count OFFSET+offset
SELECT * FROM test ORDER BY id ASC LIMIT 2 OFFSET 3;
-- 輸出
-- +----+------+-----+-----+
-- | id | name | sex | age |
-- +----+------+-----+-----+
-- | 11 | DD   | 1   |   7 |
-- | 12 | EE   | 0   |  47 |
-- +----+------+-----+-----+

 利用limit與update ,delete進行配合使用

limit 與 update,delete 進行配合使用的時候只能用LIMIT+數值的模式,表示更新或者刪除前幾條數據

--limit 與 update 配合使用
UPDATE test SET age=22 LIMIT 3;
-- 輸出
-- +----+------+-----+-----+
-- | id | name | sex | age |
-- +----+------+-----+-----+
-- |  8 | AA   | 1   |  22 |
-- |  9 | BB   | 2   |  22 |
-- | 10 | CC   | 0   |  22 |
-- | 11 | DD   | 1   |   7 |
-- | 12 | EE   | 0   |  47 |
-- | 13 | FF   | 2   |  26 |
-- | 14 | GG   | 1   |  78 |
-- +----+------+-----+-----+
-- limit 與 delete 配合使用
DELETE FROM test LIMIT 1;
-- 輸出
-- +----+------+-----+-----+
-- | id | name | sex | age |
-- +----+------+-----+-----+
-- |  9 | BB   | 2   |  22 |
-- | 10 | CC   | 0   |  22 |
-- | 11 | DD   | 1   |   7 |
-- | 12 | EE   | 0   |  47 |
-- | 13 | FF   | 2   |  26 |
-- | 14 | GG   | 1   |  78 |
-- +----+------+-----+-----+

 9、多表查詢

多表連接查詢主要分成三部份,笛卡爾積的形式,內連接,外連接三種形式。

新建測試表

--員工表
CREATE TABLE IF NOT EXISTS user(
  id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT "用戶ID",
  pid TINYINT UNSIGNED NOT NULL,
  name VARCHAR(20) NOT NULL,
  sex ENUM('0','1','2') DEFAULT "0" NOT NULL,
  age TINYINT UNSIGNED NOT NULL DEFAULT 0
)ENGINE=INNODB CHARSET=UTF8;

--創建部門表
CREATE TABLE IF NOT EXISTS part(
  id TINYINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '部門id',
  name VARCHAR(20) NOT NULL
)ENGINE='INNODB' CHARSET=UTF8;

--插入數據
INSERT part (name) VALUE ('html'),('css'),('javascript'),('php'),('java');
INSERT user (pid,name,sex,age) VALUE ('1','AA','2',22),('1','BB','2',21),('2','CC','1',24),('4','DD','1',24),('5','EE','1',28),('3','FF','2',25),('4','GG','0',23),('2','EE','1',18),('3','FF','2',27);

 笛卡爾積的形式(進行多表查詢是篩選語句不能少於n-1個)

-- 笛卡爾積連接
SELECT * FROM `emp`, `dept` WHERE emp.deptno = dept.deptno; -- 輸出
-- +-------+--------+-----------+------+------------+---------+---------+--------+--------+------------+----------+
-- | empno | ename  | job       | mgr  | hiredate   | sal     | comm    | deptno | deptno | dname      | loc      |
-- +-------+--------+-----------+------+------------+---------+---------+--------+--------+------------+----------+
-- |  7369 | SMITH  | CLERK     | 7902 | 1980-12-17 | 800.00  | NULL    |     20 |     20 | RESEARCH   | DALLAS   |
-- |  7499 | ALLEN  | SALESMAN  | 7698 | 1981-02-20 | 1600.00 | 300.00  |     30 |     30 | SALES      | CHICAGO  |
-- |  7521 | WARD   | SALESMAN  | 7698 | 1981-02-22 | 1250.00 | 500.00  |     30 |     30 | SALES      | CHICAGO  |
-- |  7566 | JONES  | MANAGER   | 7839 | 1981-04-02 | 2975.00 | NULL    |     20 |     20 | RESEARCH   | DALLAS   |
-- |  7654 | MARTIN | SALESMAN  | 7698 | 1981-09-28 | 1250.00 | 1400.00 |     30 |     30 | SALES      | CHICAGO  |
-- |  7698 | BLAKE  | MANAGER   | 7839 | 1981-05-01 | 2850.00 | NULL    |     30 |     30 | SALES      | CHICAGO  |
-- |  7782 | CLARK  | MANAGER   | 7839 | 1981-06-09 | 2450.00 | NULL    |     10 |     10 | ACCOUNTING | NEW YORK |
-- |  7788 | SCOTT  | ANALYST   | 7566 | 1987-04-19 | 3000.00 | NULL    |     20 |     20 | RESEARCH   | DALLAS   |
-- |  7839 | KING   | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL    |     10 |     10 | ACCOUNTING | NEW YORK |
-- |  7844 | TURNER | SALESMAN  | 7698 | 1981-09-08 | 1500.00 | NULL    |     30 |     30 | SALES      | CHICAGO  |
-- |  7900 | JAMES  | CLERK     | 7698 | 1981-12-03 | 950.00  | NULL    |     30 |     30 | SALES      | CHICAGO  |
-- |  7902 | FORD   | ANALYST   | 7566 | 1981-12-03 | 3000.00 | NULL    |     20 |     20 | RESEARCH   | DALLAS   |
-- |  7934 | MILLER | CLERK     | 7782 | 1982-01-23 | 1300.00 | NULL    |     10 |     10 | ACCOUNTING | NEW YORK |
-- +-------+--------+-----------+------+------------+---------+---------+--------+--------+------------+----------+

SELECT emp.*, dept.dname FROM `emp`, `dept` WHERE emp.deptno = dept.deptno;

 自連接 :在同一張表的連接查詢(就是給本表取個別名進行連接)

SELECT worker.ename, boss.ename FROM emp AS worker,emp AS boss WHERE worker.mgr=boss.empno;
-- 輸出
-- +--------+-------+
-- | ename  | ename |
-- +--------+-------+
-- | SCOTT  | JONES |
-- | FORD   | JONES |
-- | ALLEN  | BLAKE |
-- | WARD   | BLAKE |
-- | MARTIN | BLAKE |
-- | TURNER | BLAKE |
-- | JAMES  | BLAKE |
-- | MILLER | CLARK |
-- | JONES  | KING  |
-- | BLAKE  | KING  |
-- | CLARK  | KING  |
-- | SMITH  | FORD  |
-- +--------+-------+

-- 查詢和SMITH同一部門的員工
SELECT * FROM `emp` WHERE `deptno` = (SELECT `deptno` FROM `emp` WHERE `ename`="SMITH");
-- 輸出
-- +-------+-------+---------+------+------------+---------+------+--------+
-- | empno | ename | job     | mgr  | hiredate   | sal     | comm | deptno |
-- +-------+-------+---------+------+------------+---------+------+--------+
-- |  7369 | SMITH | CLERK   | 7902 | 1980-12-17 | 800.00  | NULL |     20 |
-- |  7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL |     20 |
-- |  7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL |     20 |
-- |  7902 | FORD  | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL |     20 |
-- +-------+-------+---------+------+------------+---------+------+--------+


-- 查詢10號部門都有哪些崗位,並且都有哪些員工在從事相關工作
SELECT * FROM `emp` WHERE `job` in (SELECT DISTINCT `job` FROM `emp` WHERE `deptno`=10);
-- 輸出
-- +-------+--------+-----------+------+------------+---------+------+--------+
-- | empno | ename  | job       | mgr  | hiredate   | sal     | comm | deptno |
-- +-------+--------+-----------+------+------------+---------+------+--------+
-- |  7369 | SMITH  | CLERK     | 7902 | 1980-12-17 | 800.00  | NULL |     20 |
-- |  7566 | JONES  | MANAGER   | 7839 | 1981-04-02 | 2975.00 | NULL |     20 |
-- |  7698 | BLAKE  | MANAGER   | 7839 | 1981-05-01 | 2850.00 | NULL |     30 |
-- |  7782 | CLARK  | MANAGER   | 7839 | 1981-06-09 | 2450.00 | NULL |     10 |
-- |  7839 | KING   | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL |     10 |
-- |  7900 | JAMES  | CLERK     | 7698 | 1981-12-03 | 950.00  | NULL |     30 |
-- |  7934 | MILLER | CLERK     | 7782 | 1982-01-23 | 1300.00 | NULL |     10 |
-- +-------+--------+-----------+------+------------+---------+------+--------+

-- 查詢和小明數學,語文,英語成績一樣的學生
SELECT * FROM `student` WHERE (`chinese`,`english`,`math`) = (SELECT `chinese`,`english`,`math` FROM `student` WHERE `name`='小明');



-- 表emp
-- +-------+--------+-----------+------+------------+---------+---------+--------+
-- | empno | ename  | job       | mgr  | hiredate   | sal     | comm    | deptno |
-- +-------+--------+-----------+------+------------+---------+---------+--------+
-- |  7369 | SMITH  | CLERK     | 7902 | 1980-12-17 | 800.00  | NULL    |     20 |
-- |  7499 | ALLEN  | SALESMAN  | 7698 | 1981-02-20 | 1600.00 | 300.00  |     30 |
-- |  7521 | WARD   | SALESMAN  | 7698 | 1981-02-22 | 1250.00 | 500.00  |     30 |
-- |  7566 | JONES  | MANAGER   | 7839 | 1981-04-02 | 2975.00 | NULL    |     20 |
-- |  7654 | MARTIN | SALESMAN  | 7698 | 1981-09-28 | 1250.00 | 1400.00 |     30 |
-- |  7698 | BLAKE  | MANAGER   | 7839 | 1981-05-01 | 2850.00 | NULL    |     30 |
-- |  7782 | CLARK  | MANAGER   | 7839 | 1981-06-09 | 2450.00 | NULL    |     10 |
-- |  7788 | SCOTT  | ANALYST   | 7566 | 1987-04-19 | 3000.00 | NULL    |     20 |
-- |  7839 | KING   | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL    |     10 |
-- |  7844 | TURNER | SALESMAN  | 7698 | 1981-09-08 | 1500.00 | NULL    |     30 |
-- |  7900 | JAMES  | CLERK     | 7698 | 1981-12-03 | 950.00  | NULL    |     30 |
-- |  7902 | FORD   | ANALYST   | 7566 | 1981-12-03 | 3000.00 | NULL    |     20 |
-- |  7934 | MILLER | CLERK     | 7782 | 1982-01-23 | 1300.00 | NULL    |     10 |
-- +-------+--------+-----------+------+------------+---------+---------+--------+

-- 需求:顯示高於自己部門平均工次的員工(名字,工資,部門平均工資)
SELECT
emp.ename,emp.sal,temp.avgSal
FROM `emp`, (SELECT AVG(`sal`) AS 'avgSal', `deptno` FROM `emp` GROUP BY `deptno`) AS `temp` 
WHERE emp.deptno=temp.deptno AND emp.sal>temp.avgSal;
-- 以上語句等價於下以語句
SELECT
emp.ename,emp.sal,temp.avgSal
FROM `emp`
INNER JOIN (SELECT AVG(`sal`) AS avgSal, `deptno` FROM `emp` GROUP BY `deptno`) AS temp
on emp.deptno=temp.deptno
WHERE emp.deptno=temp.deptno AND emp.sal>temp.avgSal;
-- 輸出
-- +-------+---------+-------------+
-- | ename | sal     | avgSal      |
-- +-------+---------+-------------+
-- | ALLEN | 1600.00 | 1566.666667 |
-- | JONES | 2975.00 | 2443.750000 |
-- | BLAKE | 2850.00 | 1566.666667 |
-- | SCOTT | 3000.00 | 2443.750000 |
-- | KING  | 5000.00 | 2916.666667 |
-- | FORD  | 3000.00 | 2443.750000 |
-- +-------+---------+-------------+

 內連接:表示查詢兩個表中符合連接條件的記錄(實際上就是利用where子句對兩張(多表)形成的笛卡爾積進行篩選)

-- 語法,表示只顯示兩個表之間的公共部分
SELECT 字段名稱,...FROM tab_name INNER JOIN tab_name2 ON 連接條件

-- 舉例
SELECT u.id,u.name,u.sex,u.age,p.name FROM user AS u INNER JOIN part AS p ON u.pid=p.id;
-- 輸出
-- +----+------+-----+-----+------------+
-- | id | name | sex | age | name       |
-- +----+------+-----+-----+------------+
-- |  1 | AA   | 2   |  22 | html       |
-- |  2 | BB   | 2   |  21 | html       |
-- |  3 | CC   | 1   |  24 | css        |
-- |  8 | EE   | 1   |  18 | css        |
-- |  6 | FF   | 2   |  25 | javascript |
-- |  9 | FF   | 2   |  27 | javascript |
-- |  4 | DD   | 1   |  24 | php        |
-- |  7 | GG   | 0   |  23 | php        |
-- |  5 | EE   | 1   |  28 | java       |
-- +----+------+-----+-----+------------+

 外連接:外連接主要分為兩種連接方式,左外連接與右外連接

左外連接:先顯示左表中的全部記錄,再去右表中查詢復合條件的記錄,不符合的以NULL值代替;

右外連接:先顯示右表中的全部記錄,再去左表中查詢復合條件的記錄,不符合的以NULL 值代替;

-- 語法
SELECT 字段名稱,...FROM tab_name LEFT|RIGHT JOIN tab_name2 ON 連接條件
-- 左外邊接
SELECT u.id,u.name,u.age,p.name FROM user AS u LEFT JOIN part AS p on u.pid=p.id;
-- 右外邊接
SELECT u.id,u.name,u.age,p.name FROM user AS u RIGHT JOIN part AS p on u.pid=p.id;

 10、外鍵約束(保證表的一致性,完整性)

目錄只有innodb的存儲引擎支持外鍵,並且指向的主表的值是primary key 或者是 unique

表示當添加從表數據或者修改從表數據時,所關聯的主表的外鍵指向的值是已經存在的

創建外鍵約束的方法有兩個,一個是在建表的時候指定外鍵約束,一個是動態創建外鍵約束

-- 建表時創建外鍵約束語法(注意:子表的外鍵字段和主表的字段的類型要一致),如果外鍵字段沒有創建索引,mysql會自動創建索引,后面表示是否設置級聯操作
[CONSTRAINT 外鍵名稱] FOREIGN KEY (字段名稱) REFERENCES 主表(字段名稱) [ON DELETE CASCADE ON UPDATE CASCADE];

注意:當外鍵子表下有數據的情況下,主表所對應的字段是不允許更改的,除非把子表所對應的數據刪除。

CREATE TABLE IF NOT EXISTS job(
  id TINYINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT 'JOB ID',
  name VARCHAR(20) NOT NULL
)ENGINE=INNODB CHARSET=UTF8;

CREATE TABLE IF NOT EXISTS user(
  id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '用戶ID',
  name VARCHAR(20) NOT NULL,
  age TINYINT UNSIGNED NOT NULL DEFAULT 0,
  jid TINYINT UNSIGNED NOT NULL,
  CONSTRAINT user_fk_job FOREIGN KEY (jid) REFERENCES job(id)
)ENGINE=INNODB CHARSET=UTF8;

--如果有問題輸入SET NAMES gbk;
INSERT job (name) VALUE ("行政"),("人事"),("設計"),("編程"),("銷售");
INSERT user (name,age,jid) VALUE ("小明",20,1),('小紅',23,2),('小陳',34,3),('小剛',27,4),('小列',18,5),('小小',26,4);
-- 提示刪除失敗,因為有外鍵約束
DELETE FROM job WHERE id=2;

 動態添加和刪除外鍵限制

-- 動態刪除外鍵
ALTER TABLE tab_name DROP FOREIGN KEY foreign_name;
-- 舉例
ALTER TABLE user DROP FOREIGN KEY user_fk_job;
-- 動態添加外鍵限制不指定外鍵名稱
ALTER TABLE tab_name ADD FOREIGN KEY (字段名)  REFERENCES 主表(字段名稱) [ON DELETE CASCADE ON UPDATE CASCADE];
-- 動態添加外鍵限制並且指定外鍵名稱
ALTER TABLE tab_name ADD CONSTRAINT 外鍵名稱 FOREIGN KEY (字段名)  REFERENCES 主表(字段名稱) [ON DELETE CASCADE ON UPDATE CASCADE]; 
-- 舉例
ALTER TABLE user ADD FOREIGN KEY (jid) REFERENCES job (id);

 注意:設置級聯操作,即主表進行刪除或者更新之后,所對應的子表也會相對應的更新或者刪除操作(CASCADE)

 11、子查詢(是指嵌入在其他sql查詢語句的select語名,也叫嵌套查詢)

單行子查詢=》表示只返回一行數據的子查詢語句

-- 查詢和SMITH同一部門的員工
SELECT * FROM `emp` WHERE `deptno` = (SELECT `deptno` FROM `emp` WHERE `ename`="SMITH");
-- 輸出
-- +-------+-------+---------+------+------------+---------+------+--------+
-- | empno | ename | job     | mgr  | hiredate   | sal     | comm | deptno |
-- +-------+-------+---------+------+------------+---------+------+--------+
-- |  7369 | SMITH | CLERK   | 7902 | 1980-12-17 | 800.00  | NULL |     20 |
-- |  7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL |     20 |
-- |  7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL |     20 |
-- |  7902 | FORD  | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL |     20 |
-- +-------+-------+---------+------+------------+---------+------+--------+

多行子查詢=》表示返回多行數據的子查詢語句(使用關鍵字In)

-- 查詢10號部門都有哪些崗位,並且都有哪些員工在從事相關工作
SELECT * FROM `emp` WHERE `job` in (SELECT DISTINCT `job` FROM `emp` WHERE `deptno`=10);
-- 輸出
-- +-------+--------+-----------+------+------------+---------+------+--------+
-- | empno | ename  | job       | mgr  | hiredate   | sal     | comm | deptno |
-- +-------+--------+-----------+------+------------+---------+------+--------+
-- |  7369 | SMITH  | CLERK     | 7902 | 1980-12-17 | 800.00  | NULL |     20 |
-- |  7566 | JONES  | MANAGER   | 7839 | 1981-04-02 | 2975.00 | NULL |     20 |
-- |  7698 | BLAKE  | MANAGER   | 7839 | 1981-05-01 | 2850.00 | NULL |     30 |
-- |  7782 | CLARK  | MANAGER   | 7839 | 1981-06-09 | 2450.00 | NULL |     10 |
-- |  7839 | KING   | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL |     10 |
-- |  7900 | JAMES  | CLERK     | 7698 | 1981-12-03 | 950.00  | NULL |     30 |
-- |  7934 | MILLER | CLERK     | 7782 | 1982-01-23 | 1300.00 | NULL |     10 |
-- +-------+--------+-----------+------+------------+---------+------+--------+

 內層語句的查詢結果可以作為外層語句的查詢結果,這種情況就稱作為子查詢。(注意子子查詢要放在括號里面)

由IN,NOT IN,運算符,EXISTS等引發的子查詢,以及由運算符引發的子查詢

-- 由 IN 與 NOT IN 引發的子查詢
SELECT id,name,age FROM user WHERE jid IN (SELECT id FROM job);
SELECT id,name,age FROM user WHERE jid NOT IN (SELECT id FROM job);
-- 由運算符引發的子查詢
SELECT id,name,age FROM user WHERE jid=(SELECT id FROM job WHERE name ="編程");
-- 由EXISTS引發的子查詢,表示當子查詢的記錄存在的情況下,才執行主查詢的語句
SELECT id,name,age FROM user WHERE EXISTS (SELECT id FROM job WHERE id=20);

 由 ANY SOME ALL 引發的子查詢(下圖表示的是右側所對應的值在全組中的狀態)

-- 數據展示
-- +----+------+-----+-----+
-- | id | name | age | jid |
-- +----+------+-----+-----+
-- |  1 | 小明 |  20 |   1 |
-- |  2 | 小紅 |  23 |   2 |
-- |  3 | 小陳 |  34 |   3 |
-- |  4 | 小剛 |  27 |   4 |
-- |  5 | 小列 |  18 |   5 |
-- |  6 | 小小 |  26 |   4 |
-- +----+------+-----+-----+
 SELECT name,age FROM user WHERE age>ANY(SELECT age FROM user);
--  輸出所有的結果
 SELECT name,age FROM user WHERE age>=ALL(SELECT age FROM user);
--  輸出小陳 34
 SELECT name,age FROM user WHERE age = ANY(SELECT age FROM user);
--  輸出全部記錄,因為全部都能找到匹配的
 SELECT id, name,age FROM user WHERE id<3 AND age !=ALL(SELECT age FROM user WHERE id>2);
--  輸出id為1和2的記錄

多列子查詢 =》 如果我們的一個子查詢,返回的結果是多列的,那我們就把這個子查詢叫做多列子查詢

-- 查詢和小明數學,語文,英語成績一樣的學生
SELECT * FROM `student` WHERE (`chinese`,`english`,`math`) = (SELECT `chinese`,`english`,`math` FROM `student` WHERE `name`='小明');

括號里的字段和值是一一對應的關系

 在from子句中使用的子查詢

在from子句中出現在子查詢,我們通常在會把在from中構建的臨時表當作正常表來使用

-- 表emp
-- +-------+--------+-----------+------+------------+---------+---------+--------+
-- | empno | ename  | job       | mgr  | hiredate   | sal     | comm    | deptno |
-- +-------+--------+-----------+------+------------+---------+---------+--------+
-- |  7369 | SMITH  | CLERK     | 7902 | 1980-12-17 | 800.00  | NULL    |     20 |
-- |  7499 | ALLEN  | SALESMAN  | 7698 | 1981-02-20 | 1600.00 | 300.00  |     30 |
-- |  7521 | WARD   | SALESMAN  | 7698 | 1981-02-22 | 1250.00 | 500.00  |     30 |
-- |  7566 | JONES  | MANAGER   | 7839 | 1981-04-02 | 2975.00 | NULL    |     20 |
-- |  7654 | MARTIN | SALESMAN  | 7698 | 1981-09-28 | 1250.00 | 1400.00 |     30 |
-- |  7698 | BLAKE  | MANAGER   | 7839 | 1981-05-01 | 2850.00 | NULL    |     30 |
-- |  7782 | CLARK  | MANAGER   | 7839 | 1981-06-09 | 2450.00 | NULL    |     10 |
-- |  7788 | SCOTT  | ANALYST   | 7566 | 1987-04-19 | 3000.00 | NULL    |     20 |
-- |  7839 | KING   | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL    |     10 |
-- |  7844 | TURNER | SALESMAN  | 7698 | 1981-09-08 | 1500.00 | NULL    |     30 |
-- |  7900 | JAMES  | CLERK     | 7698 | 1981-12-03 | 950.00  | NULL    |     30 |
-- |  7902 | FORD   | ANALYST   | 7566 | 1981-12-03 | 3000.00 | NULL    |     20 |
-- |  7934 | MILLER | CLERK     | 7782 | 1982-01-23 | 1300.00 | NULL    |     10 |
-- +-------+--------+-----------+------+------------+---------+---------+--------+

-- 需求:顯示高於自己部門平均工次的員工(名字,工資,部門平均工資)
SELECT
emp.ename,emp.sal,temp.avgSal
FROM `emp`, (SELECT AVG(`sal`) AS 'avgSal', `deptno` FROM `emp` GROUP BY `deptno`) AS `temp` 
WHERE emp.deptno=temp.deptno AND emp.sal>temp.avgSal;
-- 輸出
-- +-------+---------+-------------+
-- | ename | sal     | avgSal      |
-- +-------+---------+-------------+
-- | ALLEN | 1600.00 | 1566.666667 |
-- | JONES | 2975.00 | 2443.750000 |
-- | BLAKE | 2850.00 | 1566.666667 |
-- | SCOTT | 3000.00 | 2443.750000 |
-- | KING  | 5000.00 | 2916.666667 |
-- | FORD  | 3000.00 | 2443.750000 |
-- +-------+---------+-------------+

12、聯合查詢

UNION       語法:SELECT col_name,... FROM tab_name1 UNION SELECT col_name,...FROM tab_name2 

UNION ALL     語法:SELECT col_name,... FROM tab_name1 UNION  ALL SELECT col_name,...FROM tab_name2 

注意:UNION 會去掉兩個表中重復的值,而UNION ALL 只是簡單的兩個表的合並並且UNION 或者 UNION ALL 前后的col_name的列數要一致,而且列名會以第一個SELECT 的列作為字段名稱

-- 舉例,下面的名稱就是第一個SELECT的AS后面的名稱
SELECT name AS count FROM user UNION SELECT id FROM job
-- 輸出
-- +-------+
-- | count |
-- +-------+
-- | 小明     |
-- | 小紅     |
-- | 小陳     |
-- | 小剛     |
-- | 小列     |
-- | 小小    |
-- | 編程      |
-- | 1     |
-- | 2     |
-- | 3     |
-- | 4     |
-- | 5     |
-- | 7     |
-- +-------+

 13、正則表達式查詢

使用方式,用 REGEXP "匹配方式"  就可以了,相當於JS里面的test 的功能。正則的寫法同JS或者PHP一樣。

語法: SELECT 字段名稱,...FROM tab_name WHERE 字段名稱 REGEXP "匹配模式"

-- 以小開始的數據
SELECT id,name FROM user WHERE name REGEXP '^小';
-- 以程結尾的數據
SELECT id,name FROM user WHERE name REGEXP '程$';
-- 包含明,紅,剛的數據
SELECT id,name FROM user WHERE name REGEXP '明|紅|剛';

 14、mysql的三元運算符與IFNULL語句

CASE WHEN 條件 THEN 結果1 ELSE 結果2 END 語句

-- 與SUM合用
SELECT SUM(CASE WHEN c.checkresult= '合格' THEN 1 ELSE 0 END) AS qualified,
SUM(CASE WHEN c.checkresult = '不合格' THEN 1 ELSE 0 END) AS disqualification,
COUNT(*) AS count FROM tab_name WHERE [條件];
-- sql中ifnull用法:
SELECT IFNULL(x,0,1) from tab_name;
-- 解釋:如果表a中x字段是null,輸出為0,否則輸出1
-- 擴展用法:select ifnull(SUM(x),0) from a;

ifnull(express1,express2) 當express1為空時返回express2函數,當express1不為空時返回express1函數,eg sum(ifnull(x,0));

15、mysql 常用函數表(部份函數解析祥見函數那篇博客)

 

 16、mysql 事務性操作

事務用於保證數據的一致性,它由一組相關的dml(增刪改)語句組成,該組的dml語句要么全部成功,要么全部失敗。

(注意:要引用支持事務的引擎如innodb)

mysql 事務的關鍵詞

start transaction    =>    開始一個事務

savepoint    =>    保存點

rollback to   =>    回滾到某個保存點

rollback       =>    回滾

commit        =>    提交

在mysql 控制台實現事務控制

-- 插入案例表
CREATE TABLE IF NOT EXISTS `account` (
    id INT UNSIGNED NOT NULL PRIMARY KEY,
    name VARCHAR(30) NOT NULL DEFAULT '',
    money DECIMAL(10,2) UNSIGNED NOT NULL DEFAULT 0.0
)CHARSET=utf8  COLLATE=utf8_general_ci ENGINE=innodb;

INSERT INTO `account` (id, name, money) VALUES (111111, 'jim', 20000),(222222, 'jack', 32000);

 實現事務的步驟

-- 開始一個事務
START TRANSACTION
-- 聲明一個保存點
SAVEPOINT first
-- 執行增刪改操作
-- 進行回退的操作
ROLLBACK TO first
-- 如果操作完,沒有問題,那么就可以正式提交
COMMIT

 注意:當開啟事務的時候系統自動設置了一個匿名的保存點,當需要回退的時候只需要用rollback就可以了,如果設置了多個保存點,進行回退的時候,當退到前面的保存點時,那么這個保存點后面的保存點就消失了

 17、mysql 視圖的增刪查改

(1)  創建視圖

create view 視圖名 as  select 語句;

(2)  視圖的顯示

show create view 視圖名;

(3)  視圖的修改

alter view 視圖名 as  新的select 語句 ;

(4)  視圖的刪除

drop view 視圖名1, 視圖名2;

 視圖案例說明

l   以emp表為例

只讓人查詢emp的名稱,job, 其它的信息不能查詢? 這時我們就可以創建視圖來解決這個問題 。

(1)  創建視圖

create view myview as select ename, job from emp;

(2)  使用視圖和使用一個普通表示一樣樣的.

 

(3)  對視圖或者表的dml操作,會相互的影響

在視圖中所有的操作可以和正常的表一樣進行操作,如果要查看是否是視圖表可以用show create table `視圖表`

查看數據庫中都有哪些視圖用語句:show table status where comment='view'

例子=》 創建一個test的視圖

CREATE VIEW `test` AS SELECT `account`.`name`, `account`.`money` 
FROM `account` 
WHERE `account`.`money`= (SELECT MAX(`money`) FROM `account`);

使用視圖的好處

1.安全性

一些數據表有着重要的信息。有些字段是保密的,不能讓用戶直接看到。這時就可以創建一個視圖,在這張視圖中只保留一部分字段。這樣,用戶就可以查詢自己需要的字段,不能查看保密的字段。

2.性能提升

關系數據庫的數據常常會分表存儲,使用外鍵建立這些表的之間關系。這時,數據庫查詢通常會用到連接(JOIN)。這樣做不但麻煩,效率相對也比較低。如果建立一個視圖,將相關的表和字段組合在一起,就可以避免使用JOIN查詢數據。

3.靈活性提升

如果系統中有一張舊的表,這張表由於設計的問題,即將被廢棄。然而,很多應用都是基於這張表,不易修改。這時就可以建立一張視圖,視圖中的數據直接映射到新建的表。這樣,就可以少做很多改動,也達到了升級數據表的目的.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM