mysql基礎(chǔ)知識

一、數(shù)據(jù)類型

1、數(shù)字

類型 大小 說明
TINYINT 1字節(jié) 小整數(shù)(8個二進(jìn)制位,負(fù)的128到正的127)
SMALLINT 2字節(jié) 普通整數(shù)(16個二進(jìn)制位,負(fù)的2的16次冪到正的2的16次冪)
MEDIUMINT 3字節(jié) 普通整數(shù)
INT 4字節(jié) 較大整數(shù)(最常用)
BIGINT 8字節(jié) 大整數(shù)
FLOAT 4字節(jié) 單精度浮點數(shù)
DOUBLE 8字節(jié) 雙精度浮點整數(shù)
DECIMAL ------ DECIMAL(10,2),(不會丟失精度,涉及到錢等對精度要求高或者很重要的數(shù)據(jù)時用)
  • 為什么浮點數(shù)不精確,因為十進(jìn)制的浮點數(shù)轉(zhuǎn)成二進(jìn)制的浮點數(shù)會丟失精度
  • decimal精確是因為不管保存整數(shù)還是浮點數(shù),都是采用字符串的方式來保存的。 DECIMAL(10,2)其中的10表示整數(shù)位和小數(shù)位加起來一共10個字符,2表示精確到小數(shù)點后兩位

2、字符串

類型 大小 說明
CHAR 1-255字符 固定長度字符串
VARCHAR 1-65535字符 不固定長度字符串
TEXT 1-65535字符 不確定長度字符串
MEDIUMTEXT 1-1千6百萬字符 不確定長度字符串
LONGTEXT 1-42億字符 不確定長度字符串

3、日期類型

類型 大小 說明
DATE 3字節(jié) 日期
TIME 3字節(jié) 時間
YEAR 1字節(jié) 年份
DATETIME 8字節(jié) 日期時間
TIMESTAMP 4字節(jié) 時間戳

二、數(shù)據(jù)庫表的相關(guān)操作

邏輯空間對應(yīng)的是文件夾,數(shù)據(jù)表對應(yīng)的是文件夾中的.ibd文件

1、定義邏輯空間

# 展示所有的邏輯空間
SHOW DATABASES;
# 創(chuàng)建邏輯空間
CREATE DATABASE demo;
# 刪除邏輯空間
DROP DATABASE demo;
# 使用(或者說切換到) demo 邏輯空間
USE demo;

2、定義數(shù)據(jù)表

# 創(chuàng)建 student 數(shù)據(jù)表
CREATE TABLE student (
    id INT UNSIGNED PRIMARY KEY,
    name VARCHAR(20) NOT NULL,
    sex CHAR(1) NOT NULL,
    birthday DATE NOT NULL,
    tel CHAR(11) NOT NULL,
    remark VARCHAR(200)
);

# 在數(shù)據(jù)表 student 中插入數(shù)據(jù)
INSERT INTO student VALUES(1, "李強(qiáng)", "男", "1990-05-06", "13355556666", NULL);

# 查看當(dāng)前邏輯空間下所有數(shù)據(jù)表名
SHOW TABLES;
# 查看數(shù)據(jù)表 student 的表結(jié)構(gòu)
DESC student;
# 查看數(shù)據(jù)表 student 創(chuàng)建時候的sql語句
SHOW CREATE TABLE student;
# 刪除數(shù)據(jù)表 student
DROP TABLE student;

3、修改數(shù)據(jù)表結(jié)構(gòu)

# 在數(shù)據(jù)表中添加新字段
ALTER TABLE student
ADD address VARCHAR(200) NOT NULL,
ADD home_tel CHAR(11) NOT NULL;

# 修改數(shù)據(jù)表中已經(jīng)存在的字段的數(shù)據(jù)類型和約束
ALTER TABLE student
MODIFY home_tel VARCHAR(20) NOT NULL;

# 修改數(shù)據(jù)表中的字段名
ALTER TABLE student 
CHANGE address home_address VARCHAR(200) NOT NULL;

# 刪除數(shù)據(jù)表中已經(jīng)存在的字段
ALTER TABLE student
DROP home_address,
DROP home_tel;

4、字段約束

  • MySQL中的字段約束共有四種
約束名稱 關(guān)鍵字 描述
主鍵約束 PRIMARY KEY 字段值唯一,且不能為NULL
非空約束 NOT NULL 字段值不能為NULL
唯一約束 UNIQUE 字段值唯一,且可以為NULL
外鍵約束 FOREIGN KEY 保持關(guān)聯(lián)數(shù)據(jù)的邏輯性
# 創(chuàng)建部門表
CREATE TABLE t_dept(
    deptno INT UNSIGNED PRIMARY KEY,
    deptname VARCHAR(10) NOT NULL UNIQUE,
    tel CHAR(11) UNIQUE
);

# 創(chuàng)建員工表,設(shè)置外鍵關(guān)聯(lián)部門表中的 deptno
CREATE TABLE t_emp (
    empno INT UNSIGNED PRIMARY KEY,
    empname VARCHAR(20) NOT NULL,
    sex ENUM("男", "女") NOT NULL,
    deptno INT UNSIGNED NOT NULL,
    hiredate DATE NOT NULL,
    FOREIGN KEY (deptno) REFERENCES t_dept(deptno)
);

5、數(shù)據(jù)表索引

  • 數(shù)據(jù)量大,而且經(jīng)常被查詢的數(shù)據(jù)表可以設(shè)置索引
  • 索引只添加在經(jīng)常被用作檢索條件的字段的上面
  • 不要在大字段上創(chuàng)建索引(字符長度超過50的字符串)
# 創(chuàng)建數(shù)據(jù)表 t_message 并給 type字段 添加索引 idx_type
CREATE TABLE t_message (
    id INT UNSIGNED PRIMARY KEY,
    content VARCHAR(200) NOT NULL,
    type ENUM("公告", "個人通知", "通報") NOT NULL,
    create_time TIMESTAMP NOT NULL,
    INDEX idx_type(type)
);

# 展示數(shù)據(jù)表 t_message 中的索引
SHOW INDEX FROM t_message;
# 刪除數(shù)據(jù)表中的索引
DROP INDEX idx_type ON t_message;
# 給數(shù)據(jù)表中的字段 type 添加索引(下面是兩種方法)
CREATE INDEX idx_type ON t_message(type);
ALTER TABLE t_message ADD INDEX idx_type(type);

三、數(shù)據(jù)庫表的基本查詢

1、普通查詢

# 查詢數(shù)據(jù)表中所有字段信息
SELECT * FROM t_emp;
# 查詢數(shù)據(jù)表中 empno, ename, sal 三個字段的信息
SELECT empno, ename, sal FROM t_emp;
# 使用列別名
# 通常情況下, SELECT子句中使用了表達(dá)式,那么這列的名字就默認(rèn)為表達(dá)式,因此可以通過 AS 來對結(jié)果集中列名進(jìn)行重命名
SELECT
    empno,
    sal * 12 AS "income"
FROM t_emp;

2、數(shù)據(jù)分頁

# 使用LIMIT關(guān)鍵字進(jìn)行數(shù)據(jù)分頁,
SELECT ... FROM ... LIMIT 起始位置, 偏移量;
# 例子
SELECT empno, ename FROM t_emp LIMIT 0, 5;

3、排序

# 在數(shù)據(jù)表t_emp中按字段 sal 進(jìn)行升序排序,默認(rèn)就是升序(ASC寫不寫都可)
SELECT empno,ename,sal,deptno 
FROM t_emp
ORDER BY sal ASC;

# 在數(shù)據(jù)表t_emp中按字段 sal 進(jìn)行降序排序
SELECT empno,ename,sal,deptno 
FROM t_emp
ORDER BY sal DESC;

# 單個字段排序,如果有兩條數(shù)據(jù),排序字段內(nèi)容相等,那么會根據(jù)這兩條數(shù)據(jù)的主鍵升序進(jìn)行排序
# 可以設(shè)置多個排序字段,第一個字段升序排列,第二個字段降序排列
SELECT deptno,ename,sal
FROM t_emp
ORDER BY deptno ASC, sal DESC;

# ORDER BY 和 LIMIT 混合使用,可以實現(xiàn)排序加分頁的效果
# 獲取員工工資排在前五位的員工數(shù)據(jù)
SELECT empno,ename,sal
FROM t_emp
ORDER BY sal DESC LIMIT 0, 5;

4、去除重復(fù)記錄

  • 使用 DISTINCTSELECT 子句中只能查詢一列數(shù)據(jù),如果查詢多列,去除重復(fù)記錄就會失效
  • DISTINCT 關(guān)鍵字只能在 SELECT 子句中使用一次
# 獲取員工表中所有職位
SELECT DISTINCT job FROM t_emp;

5、條件查詢

比較運(yùn)算符
序號 表達(dá)式 意義 例子
1 > 大于 age > 18
2 >= 大于等于 age >= 18
3 < 小于 age < 18
4 <= 小于等于 age <= 18
5 = 等于 age = 18
6 != 不等于 age != 18
7 IN 包含 age IN(10,20,30)
8 IS NULL 為空 dept IS NULL
9 IS NOT NULL 不為空 dept IS NOT NULL
10 BETWEEN AND 范圍 sal BETWEEN 2000 AND 3000
11 LIKE 模糊查詢 ename LIKE "A%"
12 REGEXP 正則表達(dá)式 ename REGEXP "[a-zA-Z]{4}"

1、LIKE "A%"中的%表示0到多個字符的意思,哪怕沒有字符也會匹配
2、LIKE "A%" 表示以字符A開頭;LIKE "%A" 表示以字符A結(jié)尾;LIKE "%A%" 表示含有A這個字符,開頭結(jié)尾還是在中間都可以匹配,

/*
   NULL 和其它數(shù)字做加減乘除運(yùn)算,結(jié)果都為 NULL,為了做計算的時候規(guī)避這種情況
   引入IFNULL(expr1,expr2),expr1為要參與計算的參數(shù),exp2為當(dāng)expr1為NULL時候用什么值來參與運(yùn)算
*/
/*
   函數(shù)DATEDIFF(expr1,expr2),可計算兩個時間之間的差值,expr1 減去 expr2,得到的結(jié)果為天數(shù)
   函數(shù)NOW(),可以獲取當(dāng)前時間
*/

# 獲取員工表中部門編號為10,并且年收入超過15000,并且工齡超過20年的員工信息
SELECT empno,ename,sal,hiredate
FROM t_emp
WHERE deptno=10 AND ((sal+IFNULL(comm,0))*12 )>=15000
AND DATEDIFF(NOW(),hiredate)/365>=20;

# 獲取部門編號在10,20,30之間,并且入職日期在1985年之前,并且job不是SALESMAN的員工信息
SELECT empno,ename,deptno,hiredate,job
FROM t_emp
WHERE deptno IN(10,20,30) AND hiredate<"1985-01-01" AND job!="SALESMAN";
邏輯運(yùn)算符
序號 表達(dá)式 意義 例子
1 AND 與關(guān)系 age > 18 AND sex = "男"
2 OR 或關(guān)系 age > 18 OR sex="男"
3 NOT 非關(guān)系 NOT deptno = 20
4 XOR 異或關(guān)系 age > 18 XOR sex="男"
SELECT ename,deptno,sal
FROM t_emp
WHERE NOT deptno IN(10, 20) XOR sal>=5000;

1、where子句中,條件執(zhí)行的順序是從左到右的。所以我們應(yīng)該把索引條件,或者篩選掉記錄最多的條件寫在最左側(cè),這樣會提高查詢速度
2、條件查詢中各種子句執(zhí)行順序是: FROM > WHERE > GROUP BY > SELECT > ORDER BY > LIMIT

四、數(shù)據(jù)庫表的高級查詢

1、聚合函數(shù)

序號 函數(shù)名 說明
1 SUM 求和,只能用于數(shù)字類型,日期類型統(tǒng)計結(jié)果是毫秒數(shù)相加,字符類型為0
2 MAX 獲得非空值的最大值
3 MIN 獲得非空值的最小值
4 AVG 獲得非空值的平均值,非數(shù)字?jǐn)?shù)據(jù)統(tǒng)計結(jié)果為0
5 COUNT COUNT(*)用于獲得包含空值的記錄數(shù),COUNT(列名)用于獲得包含非空值的記錄數(shù)

2、分組查詢

默認(rèn)情況下匯總函數(shù)是對全表范圍內(nèi)的數(shù)據(jù)做統(tǒng)計。GROUP BY子句的作用是通過一定的規(guī)則將一個數(shù)據(jù)集劃分成若干個小的區(qū)域,然后針對每個小區(qū)域分別進(jìn)行數(shù)據(jù)匯總處理。

# 查詢每個部門里,每種職位的人員數(shù)量和平均底薪,并按部門排序
SELECT deptno,job,COUNT(*),AVG(sal + IFNULL(comm,0))
FROM t_emp
GROUP BY deptno, job 
ORDER BY deptno;

# GROUP_CONCAT()函數(shù)可以把分組查詢中的某個字段拼接成一個字符串
# 查詢每個部門內(nèi)底薪超過2000元的人數(shù)和員工姓名
SELECT deptno,GROUP_CONCAT(ename),COUNT(*)
FROM t_emp
WHERE sal>=2000
GROUP BY deptno;

1、查詢語句中如果含有GROUP BY子句,那么SELECT子句中的內(nèi)容就必須要遵守規(guī)定:SELECT子句中可以包括聚合函數(shù),或者GROUP BY子句的分組列,其余內(nèi)容均不可以出現(xiàn)在SELECT子句中
2、GROUP_CONCAT函數(shù)可以把分組查詢中的某個字段拼接成一個字符串,中間用逗號分隔

# sal不應(yīng)該出現(xiàn)在SELECT子句中,以下語句執(zhí)行會直接報錯
SELECT deptno, COUNT(*), AVG(sal), sal
FROM t_emp GROUP BY deptno;

# 直接寫ename會報語法錯誤,使用GROUP_CONCAT可以避免語法錯誤,上面的sal也一樣
SELECT deptno, COUNT(*), GROUP_CONCAT(ename)
FROM t_emp
WHERE sal>=2000
GROUP BY deptno;

WITH ROLLUP對分組結(jié)果集再次做匯總計算


# 對分組結(jié)果集再次做匯總計算
SELECT deptno, COUNT(*), AVG(sal), SUM(sal), MAX(sal), MIN(sal)
FROM t_emp
GROUP BY deptno WITH ROLLUP;

聚合函數(shù)作為查詢條件,需要引入 HAVING 子句, HAVING 子句不能獨(dú)立存在,必須依賴于 GROUP BY 子句

# 查詢每個部門中,1982年以后入職的員工超過2個人的部門編號
SELECT deptno
FROM t_emp
WHERE hiredate>"1982-01-01"
GROUP BY deptno HAVING COUNT(*)>=2
ORDER BY deptno ASC;

3、表連接查詢

表連接分為兩種:內(nèi)連接外連接
內(nèi)連接是結(jié)果集中只保留符合條件的記錄
外連接是不管符不符合連接條件,記錄都要保留在結(jié)果集中

1.內(nèi)連接

內(nèi)連接的多種語法形式

# JOIN 表連接關(guān)鍵字,ON 表連接條件
# 查詢每名員工的部門信息,下面三種寫法一樣
SELECT e.empno,e.ename,d.dname
FROM t_emp e JOIN t_dept d ON e.deptno=d.deptno;

SELECT e.empno,e.ename,d.dname
FROM t_emp e JOIN t_dept d WHERE e.deptno=d.deptno; 

SELECT e.empno,e.ename,d.dname
FROM t_emp e,t_dept d WHERE e.deptno=d.deptno;

內(nèi)連接的數(shù)據(jù)表不一定必須有同名字段,只要字段之間符合邏輯關(guān)系就可以

# 查詢每個員工的編號,姓名,部門名稱,底薪,職位,工資等級
SELECT e.empno,e.ename,d.dname,sal,job,s.grade
FROM t_emp e JOIN t_dept d ON e.deptno=d.deptno 
JOIN t_salgrade s ON e.sal BETWEEN s.losal AND s.hisal;

同一張數(shù)據(jù)表也可以做表連接

# 查詢與SCOTT相同部門的員工都有誰
#(1)符合邏輯習(xí)慣,但執(zhí)行效率低
SELECT ename
FROM t_emp
WHERE deptno=(SELECT deptno FROM t_emp WHERE ename="SCOTT") AND ename!="SCOTT";
#(2)利用表連接,執(zhí)行效率遠(yuǎn)高于(1)
# 相同數(shù)據(jù)表也可以做表連接
SELECT e2.ename
FROM t_emp e1 JOIN t_emp e2 ON e1.deptno=e2.deptno
WHERE e1.ename="SCOTT" AND e2.ename!="SCOTT";

查詢結(jié)果集也可以當(dāng)做一張表和其它表進(jìn)行連接

# 查詢底薪超過公司平均底薪的員工信息
# (1) 這種方法存在語法錯誤,ON相當(dāng)于WHERE篩選條件,不可用沒有明確值的聚合函數(shù)
SELECT e1.empno,e1.ename
FROM t_emp e1 JOIN t_emp e2 ON e1.sal>AVG(e2.sal);
#(2)將查詢結(jié)果集也當(dāng)做一張表和其它表進(jìn)行連接
SELECT e.ename,e.sal
FROM t_emp e JOIN (SELECT AVG(sal) AS avg FROM t_emp) t ON e.sal>t.avg;
# 查詢 RESEARCH 部門的人數(shù)、最高底薪、最低底薪、平均底薪、平均工齡
SELECT COUNT(*),MAX(e.sal),MIN(e.sal),AVG(e.sal),AVG(DATEDIFF(NOW(),e.hiredate))
FROM t_emp e JOIN t_dept d 
WHERE d.dname="RESEARCH";

#查詢每種職業(yè)的最高工資、最低工資、平均工資、最高工資等級和最低工資等級
SELECT 
e.job,
MAX(e.sal+IFNULL(e.comm,0)),
MIN(e.sal+IFNULL(e.comm,0)),
AVG(e.sal+IFNULL(e.comm,0)),
MAX(s.grade),
MIN(s.grade)
FROM t_emp e JOIN t_salgrade s 
ON (e.sal+IFNULL(e.comm,0)) BETWEEN s.losal AND s.hisal
GROUP BY e.job;

# 查詢每個底薪超過部門平均底薪的員工信息
SELECT e1.deptno,e1.empno,e1.ename,e1.sal,e1.comm
FROM t_emp e1 JOIN (SELECT deptno, AVG(sal) AS avg FROM t_emp GROUP BY deptno) e2 
ON e1.deptno=e2.deptno AND e1.sal>e2.avg;
2.外連接

1、外連接和內(nèi)連接的區(qū)別在于,除了符合條件的記錄之外,結(jié)果集中還會保留不符合條件的記錄。
2、左外連接就是保留左表的所有記錄,與右表做連接。如果右表有符合條件的記錄就與左表連接。如果右表沒有符合條件的記錄,就用NULL與左表連接。右外連接也是如此。

SELECT e.ename, e.deptno
FROM t_emp e
LEFT JOIN t_dept d 
ON e.deptno=d.deptno;

UNION關(guān)鍵字可以將多個查詢語句的結(jié)果集進(jìn)行合并

# 查詢每個部門的名稱和部門的人數(shù)
SELECT d.dname, COUNT(e.deptno)
FROM t_emp e RIGHT JOIN t_dept d ON e.deptno=d.deptno
GROUP BY d.deptno;

# 查詢每個部門的名稱和部門的人數(shù),如果沒有部門的員工,部門名稱用NULL代替
(
SELECT d.dname, COUNT(e.deptno)
FROM t_emp e RIGHT JOIN t_dept d ON e.deptno=d.deptno
GROUP BY d.deptno
) 
UNION
(
SELECT d.dname, COUNT(*)
FROM t_emp e LEFT JOIN t_dept d ON e.deptno=d.deptno
GROUP BY d.deptno
);
# 查詢每名員工的編號、姓名、部門、月薪、工資等級、工齡、上司編號、上司姓名、上司部門
SELECT e.empno, e.ename, d.dname, 
e.sal+IFNULL(e.comm,0), 
s.grade, FLOOR(DATEDIFF(NOW(),e.hiredate)/365),
t.empno as mempno, t.ename as mename, t.dname as mdname
FROM t_emp e LEFT JOIN t_dept d ON e.deptno=d.deptno
LEFT JOIN t_salgrade s ON e.sal BETWEEN s.losal AND s.hisal
LEFT JOIN
(SELECT e1.empno, e1.ename, d1.dname
FROM t_emp e1 JOIN t_dept d1 ON e1.deptno=d1.deptno) t
ON e.mgr=t.empno;

內(nèi)連接只保留符合條件的記錄,所以查詢條件寫在ON 子句和WHERE子句中的效果是相同的。但是外連接里,條件寫在WHERE子句里,不符合條件的記錄是會被過濾掉的,而不是保留下來。

# ON 不過濾
SELECT e.empno, e.ename, d.dname
FROM t_emp e LEFT JOIN t_dept d ON e.deptno = d.deptno
AND e.deptno = 10;

# WHERE 過濾
SELECT e.empno, e.ename, d.dname
FROM t_emp e LEFT JOIN t_dept d ON e.deptno = d.deptno
WHERE e.deptno = 10;

五、MySQL對數(shù)據(jù)的基本操作

1、INSERT語句

1、插入一條數(shù)據(jù)
INSERT INTO 表名(字段1, 字段2, ...) VALUES(值1, 值2, ...);
2、插入兩條數(shù)據(jù),多條就繼續(xù)添加
INSERT INTO 表名(字段1, 字段2, ...) VALUES(值1, 值2, ...), (值1, 值2, ...);

注:表名后面字段聲明不寫也可以執(zhí)行,但是執(zhí)行速度會受影響,因為MySQL在執(zhí)行sql語句的時候會做詞法分析,如果發(fā)現(xiàn)表名后面沒有寫字段聲明,會去查詢表結(jié)構(gòu),然后自動補(bǔ)上字段聲明,這樣的話,MySQL就不能立即執(zhí)行,需要做額外的工作,然后才會去執(zhí)行sql語句,往數(shù)據(jù)庫寫入數(shù)據(jù)。
所以,請務(wù)必在表名后寫字段聲明

# 向技術(shù)部添加一條員工記錄
INSERT INTO t_emp(empno, ename, job, mgr, hiredate, sal, comm, deptno) 
VALUES(8001, "lily", "SALESMAN", 8000, "1990-01-02", 2000, NULL, (SELECT deptno FROM t_dept WHERE dname="技術(shù)部"));

IGNORE關(guān)鍵字會讓INSERT只插入數(shù)據(jù)庫不存在沖突的記錄
INSERT IGNORE INTO 表名....;

2、UPDATE語句

UPDATE 語句用于修改表的記錄,[]中可寫可不寫
UPDATE [IGNORE] 表名
SET 字段1=值1, 字段2=值2, ...
[WHERE 條件1...]
[ORDER BY ...]
[LIMIT ...]

# 把每個員工的編號和上司的編號+1,用 ORDER BY 子句完成
UPDATE t_emp SET empno=empno+1, mgr=mgr+1 ORDER BY empno DESC;

# 把月收入前三名的員工底薪減100元,用 LIMIT 子句完成
UPDATE t_emp SET sal=sal-100 ORDER BY sal DESC LIMIT 3;

# 把10部門中,工齡超過20年的員工,底薪增加200
UPDATE t_emp SET sal=sal+200 WHERE DATEDIFF(NOW(),hiredate)/365>20 AND deptno=10;

因為相關(guān)子查詢的效率非常低,所以我們可以利用表連接的方式來改造UPDATE語句
UPDATE 表1 JOIN 表2 ON 條件 SET 字段1=值1, 字段2=值2, ...
UPDATE 表1, 表2 SET 字段1=值1, 字段2=值2, ... WHERE 條件

# 把ALLEN調(diào)往RESEARCH部門,職務(wù)調(diào)整為ANALYST

# 方法1:利用子查詢,這種在SET中的子查詢是相關(guān)子查詢,改變一條數(shù)據(jù)還可以使用,但是同時改變多條數(shù)據(jù)的時候,效率會很低
UPDATE t_emp SET job="ANALYST", deptno=(SELECT deptno FROM t_dept WHERE dname="RESEARCH") WHERE ename="ALLEN"; 

# 方法2:利用表連接,JOIN可以寫成, 推薦
UPDATE t_emp e JOIN t_dept d SET e.job="ANALYST", e.deptno=d.deptno WHERE e.ename="ALLEN" AND d.dname="RESEARCH";
UPDATE t_emp e, t_dept d SET e.job="ANALYST", e.deptno=d.deptno WHERE e.ename="ALLEN" AND d.dname="RESEARCH";

# 把底薪低于公司平均底薪的員工,底薪增加150元,下面兩種寫法一樣
UPDATE t_emp e JOIN (SELECT AVG(sal) AS avg FROM t_emp) t SET e.sal=e.sal+150 WHERE e.sal<t.avg;
UPDATE t_emp e JOIN (SELECT AVG(sal) AS avg FROM t_emp) t ON e.sal<t.avg SET e.sal=e.sal+150;

UPDATE語句的表連接可以是內(nèi)連接,又可以是外連接
UPDATE 表1 [LEFT | RIGHT] JOIN 表2 ON 條件 SET 字段1=值1, 字段2=值2, ...

# 把沒有部門的員工,或者SALES部門低于2000元底薪的員工,都調(diào)往20部門
UPDATE t_emp e LEFT JOIN t_dept d ON e.deptno=d.deptno
SET e.deptno=20 
WHERE e.deptno IS NULL OR (d.dname="SALES" AND e.sal<2000);

3、DELETE語句

DELETE 語句用于刪除記錄,[]中可寫可不寫
DELETE [IGNORE] FROM 表名
[WHERE 條件, 條件2, ...]
[ORDER BY ...]
[LIMIT ...]

# 刪除10部門中,工齡超過20年的員工記錄
DELETE FROM t_emp WHERE deptno=10 AND DATEDIFF(NOW(),hiredate)/365>20; 

# 刪除20部門中工資最高的員工記錄
DELETE FROM t_emp WHERE deptno=20 ORDER BY sal+IFNULL(comm,0) DESC LIMIT 1;

因為相關(guān)子查詢效率非常低,所以我們可以用表連接的方式來改造DELETE語句
DELETE 表1, ... FROM 表1 JOIN 表2 ON 條件
WHERE 條件1, 條件2, ...
ORDER BY ...
LIMIT ...

# 刪除SALES部門和該部門的全部員工記錄
DELETE e, d
FROM t_emp e JOIN t_dept d ON e.deptno=d.deptno
WHERE d.dname="SALES";

# 刪除每個低于部門平均底薪的員工記錄
DELETE e
FROM t_emp e JOIN (SELECT deptno, AVG(sal) AS avg FROM t_emp GROUP BY deptno) t
ON e.deptno=t.deptno AND e.sal<t.avg;

# 刪除員工KING和他的直接下屬的員工記錄,用表連接實現(xiàn)
DELETE e
FROM t_emp e JOIN
(SELECT empno FROM t_emp WHERE ename="KING") t
ON e.mgr=t.empno OR e.empno=t.empno;

DELETE語句的表連接既可以是內(nèi)連接,又可以是外連接
DELETE 表1, ... FROM 表1 [LEFT | RIGHT] JOIN 表2 ON 條件...

# 刪除SALES部門的員工,以及沒有部門的員工,下面兩種方法都可,推薦第二種
DELETE e
FROM t_emp e JOIN (SELECT deptno FROM t_dept WHERE dname="SALES") t
ON e.deptno=t.deptno OR e.deptno IS NULL;

DELETE e
FROM t_emp e LEFT JOIN t_dept d ON e.deptno=d.deptno
WHERE d.dname="SALES" OR e.deptno IS NULL;

快速刪除數(shù)據(jù)表全部記錄
1、DELETE語句是在事務(wù)機(jī)制下刪除記錄,刪除記錄之前,先把將要刪除的記錄保存到日志文件里,然后再刪除記錄
2、TRUNCATE語句在事務(wù)機(jī)制之外刪除記錄,速度遠(yuǎn)超過DELETE語句
3、語法如下:
TRUNCATE TABLE 表名;

# 刪除員工表中的所有數(shù)據(jù)
TRUNCATE TABLE t_emp;

六、MySQL基本函數(shù)的使用

1、數(shù)字函數(shù)

函數(shù) 功能 用例
ABS 絕對值 ABS(-100)
ROUND 四舍五入 ROUND(4.62)
FLOOR 強(qiáng)制舍位到最近的整數(shù) FLOOR(9.9)
CEIL 強(qiáng)制進(jìn)位到最近的整數(shù) CEIL(3.2)
POWER 冪函數(shù) POWER(2,3)
LOG 對數(shù)函數(shù) LOG(7,3)
LN 對數(shù)函數(shù) LN(10)

ROUND():四舍五入
CEIL():進(jìn)位
FLOOR():舍位

# 四舍五入
SELECT ROUND(1.4); // 1
SELECT ROUND(1.5); // 2

# 進(jìn)位
SELECT CEIL(1.1); // 2

# 舍位
SELECT FLOOR(1.9); // 1
函數(shù) 功能 用例
SQRT 開平方 SQRT(9)
PI 圓周率 PI()
SIN 三角函數(shù) SIN(1)
COS 三角函數(shù) COS(1)
TAN 三角函數(shù) TAN(1)
COT 三角函數(shù) COT(1)
PADIANS 角度轉(zhuǎn)換弧度 PADIANS(30)
DEGREES 弧度轉(zhuǎn)換角度 DEGREES(1)

2、字符函數(shù)

函數(shù) 功能 用例
LOWER 轉(zhuǎn)換小寫字符 LOWER(ename)
UPPER 轉(zhuǎn)換大寫字符 UPPER(ename)
LENGTH 字符數(shù)量 LENGTH(ename)
CONCAT 連接字符串 CONCAT(sal, "$")
INSTR 字符出現(xiàn)的位置 INSTR(ename, "A")
INSERT 插入/替換字符 INSERT("你好", 1, 0, "先生")
REPLACE 替換字符 REPLACE("你好先生", "先生", "女士")
函數(shù) 功能 用例
SUBSTR 截取字符串 SUBSTR("你好世界", 3, 4)
SUBSTRING 截取字符串 SUBSTRING("你好世界", 3, 2)
LPAD 左側(cè)填充字符 LPAD("Hello", 10, "*")
RPAD 右側(cè)填充字符 RPAD("Hello", 10, "*")
TRIM 去除首尾空格 TRIM(" 你好世界 ")

3、日期函數(shù)

函數(shù) 功能 格式
NOW() 獲得系統(tǒng)日期和時間 yyyy-MM-dd hh:mm:ss
CURDATE() 獲取當(dāng)前系統(tǒng)日期 yyyy-MM-dd
CURTIME() 獲取當(dāng)前系統(tǒng)時間 hh:mm:ss

DATE_FORMAT()函數(shù)用于格式化日期,返回用戶想要的日期格式
DATE_FORMAT(date,format)
date:日期,format:表達(dá)式

# 獲取員工姓名和入職年份
SELECT ename, DATE_FORMAT(hiredate,"%Y") FROM t_emp;
占位符 作用 占位符 作用
%Y 年份 %m 月份
%d 日期 %w 星期(數(shù)字)
%W 星期(名稱) %j 本年第幾天
%U 本年第幾周 %H 小時(24)
%h 小時(12) %i 分鐘
%s %r 時間(12)
%T 時間(24)
# 利用日期函數(shù),查詢明年你的生日是星期幾
SELECT DATE_FORMAT("2023-11-13","%w"); // 0代表周天
SELECT DATE_FORMAT("2023-11-13","%W");

# 利用日期函數(shù),查詢1981年上半年入職的員工有多少人
SELECT ename, hiredate FROM t_emp 
WHERE (DATE_FORMAT(hiredate,"%Y") = 1981) AND DATE_FORMAT(hiredate,"%m") < 7;

MySQL數(shù)據(jù)庫里面,兩個日期不能直接加減,日期也不能與數(shù)字加減
DATE_ADD()函數(shù)可以實現(xiàn)日期的偏移計算,而且時間單位很靈活
DATE_ADD(日期,INTERVAL 偏移量 時間單位)

# 15天之后的時間
SELECT DATE_ADD(NOW(),INTERVAL 15 DAY);

# 300分鐘之前的時間
SELECT DATE_ADD(NOW(),INTERVAL -300 MINUTE);

# 6個月零3天之前的時間
SELECT DATE_ADD(DATE_ADD(NOW(),INTERVAL -6 M  ONTH),INTERVAL -3 DAY);

計算日期之間相隔的天數(shù)
DATEDIFF()函數(shù)用來計算兩個日期之間相差的天數(shù)
DATEDIFF(日期,日期)

4、條件函數(shù)

SQL語句中可以利用條件函數(shù)來實現(xiàn)編程語言里的條件判斷
IFNULL(表達(dá)式, 值)
IF(表達(dá)式, 值1, 值2)

# 中秋節(jié)公司發(fā)放禮品,SALES部門發(fā)放禮品A,其余部門發(fā)放禮品B,打印每名員工獲得的禮品
SELECT e.ename, d.deptno, d.dname, IF(d.dname="SALES","A","B")
FROM t_emp e JOIN t_dept d
WHERE e.deptno=d.deptno;

復(fù)雜的條件判斷可以用條件語句來實現(xiàn),比IF語句更強(qiáng)大
CASE
WHERE 表達(dá)式 THEN 值1
WHERE 表達(dá)式 THEN 值2
......
ELSE 值N
END

# 公司年慶決定組織員工集體旅游,每個部門旅游目的地是不同的。SALES部門去P1地點,ACCOUNTING部門去P2地點,RESEARCH部門去P3地點,查詢每名員工的旅行地點。
SELECT
    e.ename,
    CASE 
    WHEN d.dname="SALES" THEN "P1"
    WHEN d.dname="ACCOUNTING" THEN "P2"
    WHEN d.dname="RESEARCH" THEN "P3"
    END AS PLACE
FROM t_emp e JOIN t_dept d
WHERE e.deptno=d.deptno;

# 公司決定為員工調(diào)整基本工資,具體調(diào)整方案如下
# 1、SALES部門中工齡超過20年,漲幅10%
# 2、SALES部門中工齡不滿20年,漲幅5%
# 3、ACCOUNTING部門, +300元
# 4、RESEARCH部門里低于部門平均底薪, +200元
# 5、沒有部門的員工, +100元
UPDATE t_emp e LEFT JOIN t_dept d ON e.deptno=d.deptno 
LEFT JOIN (SELECT deptno, AVG(sal) AS avg FROM t_emp GROUP BY deptno) t ON e.deptno=t.deptno
SET e.sal=(
    CASE
    WHEN d.dname="SALES" AND DATEDIFF(NOW(),e.hiredate)/365>20 THEN e.sal*1.1
    WHEN d.dname="SALES" AND DATEDIFF(NOW(),e.hiredate)<20 THEN e.sal*1.05
    WHEN d.dname="ACCOUNTING" THEN e.sal+300
    WHEN d.dname="RESEARCH" AND e.sal<t.avg THEN e.sal+200
    WHEN d.dname IS NULL THEN e.sal+100
    ELSE e.sal
    END
);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 第1章 初識MySQL 1.1 數(shù)據(jù)庫基礎(chǔ) 1.1.1 什么是數(shù)據(jù)庫 1.1.2 表 1.1.3 數(shù)據(jù)類型 1.1...
    _Cappuccino_閱讀 12,729評論 0 0
  • 一、什么是數(shù)據(jù)庫 ?數(shù)據(jù)庫是按照數(shù)據(jù)結(jié)構(gòu)來組織,存儲和管理數(shù)據(jù)的倉庫,數(shù)據(jù)庫是存儲數(shù)據(jù)的集合的單獨(dú)的應(yīng)用程序。每個...
    wujimozun閱讀 239評論 0 0
  • 1. mysql 基本數(shù)據(jù)類型以及長度 類型大小范圍(有符號)范圍(無符號)用途 TINYINT1 字節(jié)(-128...
    596_19b5閱讀 158評論 0 0
  • MYSQL簡介 MySQL是一個開源的關(guān)系型數(shù)據(jù)庫管理系統(tǒng),也是最流行的關(guān)系型數(shù)據(jù)庫管理系統(tǒng)之一,使用標(biāo)準(zhǔn)化的 S...
    geekdeedy閱讀 543評論 0 0
  • 一、MySQL簡介 MySQL是一種開放源代碼的關(guān)系型數(shù)據(jù)庫管理系統(tǒng),使用最常用的數(shù)據(jù)庫管理語言--結(jié)構(gòu)化查詢語言...
    乙哥驛站閱讀 681評論 0 0

友情鏈接更多精彩內(nèi)容