使用SQlyog管理工具:
1. 工具創建數據庫:
數據庫字符集:存什麼字符就要選什麼編碼,如:要是中文就要選utf8
數據庫校對規則:字符在比較時要遵循一定的規則,如:中文編碼規則,不區分大小寫要選utf8_general_ci
2. 工具建表
①顯示錶結構:desc表名
②顯示錶創建語句:show create table 表名
3. 字段的約束及屬性
名稱 |
關鍵字 |
說明 |
非空約束 |
NOT NULL |
字段不允許爲空 |
默認約束 |
DEFAULT |
賦予某字段默認值 |
唯一約束 |
UNIQUE KEY(UK) |
設置字段的值是唯一的 允許爲空,但只能有一個空值 |
主鍵約束 |
PRIMARY KEY(PK) |
設置該字段爲表的主鍵 可唯一標識該表記錄,不能有空值 |
外鍵約束 |
FOREIGN KEY(FK) |
用於在兩表之間建立關係 需要指定引用主表的哪一字段 |
自動增長 |
AUTO_INCREMENT |
設置該列爲自增字段 默認每條自增1 通常用於設置主鍵 |
①主鍵
CREATE TABLE student(
`studentNo` INT(4) PRIMARY KEY,
……);
②註釋
CREATE TABLE [IF NOT EXISTS] `表名` (
`字段1` 數據類型 [字段屬性|約束] [索引] [註釋(comment)],
`字段2` 數據類型 [字段屬性|約束] [索引] [註釋],
……
`字段n` 數據類型 [字段屬性|約束] [索引] [註釋]
)[表類型] [表字符集] [註釋];
CREATE TABLE test (
`id` int(11) UNSIGNED COMMENT ‘編號’
)COMMENT='測試表’;
③設置字符集編碼
a. 給表設字符集:
CREATE TABLE [IF NOT EXISTS] 表名(
#省略代碼
)CHARSET = 字符集名;
b. 給庫設字符集:
CREATE DATABASE ******/*!40100 DEFAULT CHARACTER SET utf8 */
c. 給列設字符集
CREATE TABLE a(
address CHAR(5) CHARACTER SET gbk
)
④設置表的類型
MySQL的數據表的類型:
MyISAM、InnoDB、HEAP、 BOB、CSV等
常見的MyISAM與InnoDB類型
名稱 |
MylSAM |
InnoDB |
事務處理 |
不支持 |
支持 |
數據行鎖定 |
不支持 |
支持 |
外鍵約束 |
不支持 |
支持 |
全文索引 |
支持 |
不支持 |
表空間大小 |
較小 |
較大,約2倍 |
CREATE TABLE [IF NOT EXISTS] 表名(
#省略代碼
)ENGINE = MyISAM;
或者
CREATE TABLE表名(
#省略代碼
)ENGINE= InnoDB;
適用場合:
- 使用MyISAM:節約空間及響應速度快;不需事務,空間小,以查詢訪問爲主
- 使用InnoDB:安全性,事務處理及多用戶操作數據表;多刪除、更新操作,安全性高,事務處理及併發控制
注:查看mysql所支持的引擎類型(表類型)的方法:SHOW ENGINES;
查看默認引擎:SHOW VARIABLES LIKE 'storage_engine';
修改存儲引擎:修改my.ini配置文件:default-storage-engine= InnoDB
【改爲其他存儲存儲】
數據表的存儲位置:
MySQL數據表以文件方式存放在磁盤中:
- 包括表文件、數據文件以及數據庫的選項文件
- 位置:MySQL安裝目錄\data下存放數據表。目錄名對應數據庫名,該目錄下文件名對應數據表
注:
InnoDB類型數據表只有一個*. frm文件,以及上一級目錄的ibdata1文件
MylSAM類型數據表對應三個文件:
*. frm —— 表結構定義文件
*. MYD —— 數據文件
*. MYI —— 索引文件
存儲位置:因操作系統而異,可查my.ini
datadir= "C:/ProgramData/MySQL/MySQL Server 5.5/Data/"
innodb_data_home_dir="D:/MySQL Datafiles/"
數據庫數據管理:
1. 數據庫意義
①數據存儲
②數據管理
2. 管理數據庫數據方法
①通過SQLyog等管理工具管理數據庫數據
②通過DML語句管理數據庫數據
DML語言(數據操作語言):
用於操作數據庫對象中所包含的數據:
包括:
①INSERT(添加數據語句)
②UPDATE(更新數據語句)
③DELETE(刪除數據語句)
1. 添加數據:INSERT命令
語法:INSERT INTO 表名 [(字段1,字段2,字段3,……)] VALUES (' 值1' ,'值2', '值3', '值4',……);
注:
①字段名是可選的,如省略則依次插入所有字段;字段或值之間用英文逗號隔開
②"字段1,字段2…"該部分可省略,但添加的值務必與表結構數據列順序相對應,且數量一致;如插入的是表中部分數據,字段名列表必填
③可同時插入多條數據,values後用英文逗號隔開
示例:
#使用語句如何增加數據
INSERT INTO grade(gradename) VALUES('大一'); 【儘量用這種寫全的帶自增的方法】
INSERT INTO grade VALUES(5,'大二');
INSERT INTO grade VALUES(6,'大二');
2. 插入多條數據記錄
語法:INSERT INTO 表名 [(字段1,字段2,字段3,……)] VALUES (' 值1' ,'值2', '值3', '值4',……),(' 值1' ,'值2', '值3', '值4',……);
【這種寫法是MySQL裏面獨有的其他數據庫沒有,而且爲避免表結構發生變化引發的錯誤,建議插入數據時寫明具體字段名】
示例:
INSERT INTO grade(gradename) VALUES('大三'),("大四");
INSERT INTO student(studentno,studentname,sex,gradeid,phone,address,birthday,email,identitycard)
VALUES(1001,'張三',DEFAULT,5,'13833301425',NULL,NOW(),NULL,'22432432'),
(1002,'張',2,5,'144443301425','北京',NOW(),'[email protected]','2343243243242')
【NOW()代表當前時間是一個函數】
3. 將查詢結果插入新表
語法:CREATE TABLE 新表(SELECT 字段1,字段2…… FROM 原表);
如新表已存在,不能重複創建
示例:
CREATE TABLE `phoneList`(
SELECT `studentName`,`phone` FROM `student`);
4. 數據更新:UPDATE命令
語法:UPDATE表名SET column_name= value [,column_name2 = value2,…] [ WHERE condition];
注:
①column_name 爲要更改的數據列
②value爲修改後的數據,可以爲變量、具體值、表達式或者嵌套的SELECT結果
③condition爲篩選條件,如不指定則修改該表的所有列數據
示例:
#使用語句修改數據
#將張三的地址改爲中國南京
UPDATE student SET address='中國南京' WHERE studentno=1001
UPDATE student SET sex = ‘女’;
#同時修改多列
UPDATE student SET address='中國南京',email='[email protected]' WHERE studentno=1001
5. WHERE條件子句
①簡單理解爲:有條件地從表中篩選數據
②WHERE中的運算符
運算符 |
含義 |
範例 |
結果 |
= |
等於 |
5=6 |
false |
<>或!= |
不等於 |
5!=6 |
true |
> |
大於 |
5>6 |
false |
< |
小於 |
5<6 |
true |
>= |
大於等於 |
5>=6 |
false |
<= |
小於等於 |
5<=6 |
true |
BETWEEN |
在某個範圍之間 |
BETWEEN 5 AND 10 |
- |
AND |
並且 |
5>1 AND 1>2 |
false |
OR |
或 |
5>1 0R 1>2 |
true |
示例:
#條件可以使用運算符
UPDATE student SET sex=1 WHERE studentno=1001 OR studentno=1002 OR studentno=1003 OR studentno=1004
UPDATE student SET sex=2 WHERE studentno>=1001 AND studentno<=1004
UPDATE student SET sex=1 WHERE studentno BETWEEN 1001 AND 1004
#使用函數
UPDATE student SET studentname=CONCAT("姓名:",studentname)
6. 刪除數據:DELETE命令(有主外鍵關係的都刪不了)
語法:
#該表表類型(存儲引擎)InnoDB
DELETE FROM表名 [WHERE condition ];
注:condition爲篩選條件,如不指定則刪除該表的所有列數據
示例一:
#刪除數據
DELETE FROM grade WHERE gradeid=7;
示例:
CREATE TABLE test(
id INT(4) PRIMARY KEY AUTO_INCREMENT,
coll VARCHAR(20) NOT NULL
);
INSERT INTO test(coll) VALUES('row1'),('row2'),('row3');
#刪除表全部數據(不帶where條件的delete)
#自增的當前值依然從原來的基礎上進行
DELETE FROM test;
INSERT INTO test(coll) VALUES('row1'),('row2'),('row3');
【執行刪除之後再次執行插入操作序號會從4,5,6開始計數;刪除時會一行一行刪除並記錄日誌】
示例二
#創建兩個表,存儲引擎分別爲InnoDB和MyISAM
CREATE TABLE test1(
id INT(4) PRIMARY KEY AUTO_INCREMENT,
coll VARCHAR(20) NOT NULL
)ENGINE=INNODB;
CREATE TABLE test2(
id INT(4) PRIMARY KEY AUTO_INCREMENT,
coll VARCHAR(20) NOT NULL
)ENGINE=MYISAM;
INSERT INTO test1(coll) VALUES('row1'),('row2'),('row3');
INSERT INTO test2(coll) VALUES('row1'),('row2'),('row3');
#清空表數據
DELETE FROM test1;
DELETE FROM test2;
#id-->6
#重啓數據庫服務後,test1:1,2,3;test2:7,8,9
#同樣使用delete from清空數據庫服務後,對於InnoDB的表,自增列從初始值重新開始(該數據放到內存裏斷電即失)
#而MyISAM類型的表,自增列依然從上一個自增數據基礎上開始(該數據放到文件裏能保存下來,不管怎樣重啓數據庫文件都丟不了)
7. 刪除數據:TRUNCATE命令(有主外鍵關係的都刪不了)
用於完全清空表數據,但表結構、索引、約束等不變
語法:TRUNCATE [TABLE] table_name
示例:
#該表表類型(存儲引擎)InnoDB
CREATE TABLE test(
id INT(4) PRIMARY KEY AUTO_INCREMENT,
coll VARCHAR(20) NOT NULL
);
INSERT INTO test(coll) VALUES('row1'),('row2'),('row3');
#刪除表數據(truncate)
#自增值恢復到初始值重新開始
TRUNCATE TABLE test;
INSERT INTO test(coll) VALUES('row1'),('row2'),('row3');
【執行之後會接着從1,2,3開始計數;在刪除時會把記錄全部刪除也不會記錄日誌】
TRUNCATE命令和DELETE命令的區別:
①相同:都能刪除數據、不刪除表結構,但TRUNCATE速度更快
②不同:
- 使用TRUNCATE TABLE重新設置AUTO_INCREMENT計數器
- 使用TRUNCATE TABLE不會對事務有影響
DQL(Data Query Language)語言:數據查詢語言
①查詢數據庫數據,如SELECT語句
②簡單的單表查詢或多表的複雜查詢和嵌套查詢
③數據庫語言中最核心、最重要的語句
④使用頻率最高的語句
查詢語法SELECT:
SELECT [ALL | DISTINCT]
{ * | table.* | [table.field1 [as alias1] [,table.field2 [as alias2]] [,…]] }
FROM table_name [as table_alias ]
[left | out | inner join table_name2 ] #聯合查詢
[WHERE …] #指定結果需滿足的條件
[GROUP BY …] #指定結果按照哪幾個字段來分組
[HAVING …] #過濾分組的記錄必須滿足的次要條件
[ORDER BY …] #指定查詢記錄按一個或者多個條件排序
[ LIMIT { [ offset,] row_count | row_count OFFSET offset }]; #指定查詢的記錄從哪條至哪條
【上面的順序是固定的】
注:
[ ]括號代表可選的;
{ }括號代表必須的;
# 代表MySQL語句中的註釋符,也可以用 /*該處爲註釋*/
where條件語句:
語法:
SELECT [ALL | DISTINCT]
{ * | table.* | [table.field1 [as alias1] [,table.field2 [as alias2]] [,…]] }
FROM table_name [as table_alias ]
[left | out | inner join table_name2 ] #聯合查詢
[WHERE …] #指定結果需滿足的條件
[GROUP BY …] #指定結果按照哪幾個字段來分組
[HAVING …] #過濾分組的記錄必須滿足的次要條件
[ORDER BY …] #指定查詢記錄按一個或者多個條件排序
[ LIMIT { [ offset,] row_count | row_count OFFSET offset }]; #指定查詢的記錄從哪條至哪條
- 用於檢索數據表中符合條件的記錄
- 搜索條件可由一個或多個邏輯表達式組成,結果一般爲真或假
- 搜索條件的組成
①邏輯操作符
操作符名稱 |
語法 |
描述 |
AND 或 && |
a AND b或a && b |
邏輯與,同時爲真結果才爲真 |
OR 或 || |
a OR b或a || b |
邏輯或,只要一個爲真,則結果爲真 |
NOT 或 ! |
NOT a或 ! a |
邏輯非,若操作數爲假,結果則爲真 |
②比較操作符
操作符名稱 |
語法 |
描述 |
IS NULL |
a IS NULL |
若操作符爲NULL則結果爲真 |
IS NOT NULL |
a IS NOT NULL |
著操作符不爲NULL.則結果爲真 |
BETMEEN |
a BETWEEN b AND c |
著a範圍在b與c之間則結果爲真 |
LIKE |
a LIKE b |
SOL模式匹配,若a匹配b,則結果爲真 |
IN |
a IN (a1,a2,a3,…) |
若a等於a1,a2…中的某一個,則結果爲真 |
注:
- 數值數據類型的記錄之間才能進行算術運算
- 相同數據類型的數據之間才能進行比較
簡單查詢語句彙總示例:
1. 查詢所有學生信息(所有列,效率低)
SELECT * FROM student;
#查詢指定列(學號,姓名)
SELECT studentno,studentname FROM student;
2. 取別名(原表裏的名字沒有變,隻影響了查詢出來的結果,想修改原表數據要update)
SELECT studentno AS 學號,studentname AS 姓名 FROM student;
#AS可以省略
SELECT studentno 學號,studentname 姓名 FROM student;
#使用as也可以爲表取別名(作用:單表查詢意義不大,但是當多個表的時候取別名就好操作,當不同的表裏有相同名字的列的時候區分就會好區分)
SELECT studentno AS 學號,studentname AS 姓名 FROM student AS s;
#給表取別名的AS也可以省略
SELECT studentno 學號,studentname 姓名 FROM student s;
3. 使用CONCAT,爲查詢結果取一個新名字
SELECT CONCAT('姓名:',studentname) AS 新姓名 FROM student;
#查看考試成績
SELECT * FROM result;
#查看哪些同學參加了考試(學號)
SELECT studentno FROM result;
#查看哪些同學參加了考試(學號)——去除重複項(distinct,默認是all)
SELECT DISTINCT studentno FROM result;
4. SELECT查詢中可以使用表達式
SELECT @@auto_increment_increment
SELECT VERSION()
SELECT 100*3-1 AS 計算結果
#給學員考試成績集體提分1分
SELECT studentno,studentresult+1 AS '提分後' FROM result;
#滿足條件的查詢(where)考試
SELECT studentno,studentresult
FROM result
WHERE studentresult >=95 AND studentresult<=100;
5. 精確查詢
SELECT studentno,studentresult
FROM result
WHERE studentno=1000;
#除了1000號同學,我要其他同學的考試成績
SELECT studentno,studentresult
FROM result
WHERE studentno!=1000;
SELECT studentno,studentresult
FROM result
WHERE NOT studentno=1000;
6. 模糊查詢 between and\ like \in \ is null\ is not null
SELECT studentno,studentresult
FROM result
WHERE studentresult BETWEEN 95 AND 100;
#或者寫成
SELECT studentno,studentresult
FROM result
WHERE studentresult >=95 && studentresult<=100;
#查詢姓李的同學的學號及姓名
7. 模糊查詢中like結合使用的通配符:%(0到任意個字符) _ (一個字符) 【like使用的通配符就這兩個】
SELECT studentno,studentname
FROM student
WHERE studentname LIKE '李%';
#姓李的,但是名字中只有一個字
SELECT studentno,studentname
FROM student
WHERE studentname LIKE '李_';
#姓李的,但是名字中只有兩個字
#一個_代表一個字,兩個_代表兩個字
SELECT studentno,studentname
FROM student
WHERE studentname LIKE '李_';
SELECT studentno,studentname
FROM student
WHERE studentname LIKE '李__';
#想要先輸出兩個字的後輸出三個字的
SELECT studentno,studentname FROM student
WHERE studentname LIKE '李_';
UNION
SELECT studentno,studentname FROM student
WHERE studentname LIKE '李__';
#姓名中含有“文”字的同學
SELECT studentno,studentname
FROM student
WHERE studentname LIKE '%文%';
8. 查詢有%號的同學的學號及姓名(此時要使用轉義符\)
SELECT studentno,studentname
FROM student
WHERE studentname LIKE '%\%%';
#查詢有_號的同學的學號及姓名
SELECT studentno,studentname
FROM student
WHERE studentname LIKE '%\_%';
#轉義符\ 使用ESCAPE關鍵字,來使用自己的轉義符(:)
SELECT studentno,studentname
FROM student
WHERE studentname LIKE '%:%%' ESCAPE ':';
9. 模糊查詢:in null
SELECT studentno,studentname
FROM student
WHERE studentno IN(1000,1001,1002,1003)
SELECT studentno,studentname
FROM student
WHERE address IN('北京','安徽','蘇州','揚州');
10. null 空
#查詢出生日期沒有填寫的同學
#=null 是錯誤的
SELECT studentno,studentname
FROM student
WHERE borndate=NULL;
#和null比較必須寫is null
SELECT studentno,studentname
FROM student
WHERE borndate IS NULL;
#查詢出生日期填寫的同學,也就是出生日期不爲空的同學
SELECT studentno,studentname
FROM student
WHERE borndate IS NOT NULL;
11. 區別空字符串與null
#查詢家庭住址沒有填寫的同學,是沒有填寫同時包括爲null的,要寫在一起
SELECT studentno,studentname
FROM student
WHERE address="" OR address IS NULL;
EXISTS子查詢:
語法:
SELECT …… FROM 表名 WHERE EXISTS(子查詢);
子查詢有返回結果: EXISTS子查詢結果爲TRUE
子查詢無返回結果: EXISTS子查詢結果爲FALSE,外層查詢不執行
注:
相關子查詢,非相關子查詢
非相關子查詢示例:
SELECT r.studentNo,r.`studentResult`
FROM result r WHERE
EXISTS(SELECT * FROM result t WHERE
t.studentResult>=80)
相關子查詢示例:
SELECT r.studentNo,r.`studentResult`
FROM result r WHERE
EXISTS(SELECT * FROM result t WHERE
t.studentResult>=80
AND r.` studentNo `=t.` studentNo `)
連接查詢:
SELECT [ALL | DISTINCT]
{ * | table.* | [table.field1 [as alias1] [,table.field2 [as alias2]] [,…]] }
FROM table_name [as table_alias ]
[left | out | inner join table_name2 ] #聯合查詢
[WHERE …] #指定結果需滿足的條件
[GROUP BY …] #指定結果按照哪幾個字段來分組
[HAVING …] #過濾分組的記錄必須滿足的次要條件
[ORDER BY …] #指定查詢記錄按一個或者多個條件排序
[ LIMIT { [ offset,] row_count | row_count OFFSET offset }];#指定查詢的記錄從哪條至哪條
1. 內連接 inner join
查詢兩個表中的結果集中的交集
方法一:
SELECT `student`.`studentName`,`result`.`subjectNo`,`result`.`studentResult`
FROM `student`,`result`
WHERE `student`.`studentNo` = `result`.`studentNo`;
方法二:
SELECT s.`studentName`,r.`subjectNo`,r.`studentResult`
FROM `student` AS s
INNER JOIN `result` AS r ON (s.`studentNo` = r.`studentNo`);
三個表內連接的方法:
方法一:
SELECT s.`studentName`,r.`studentResult`,sub.SubjectName
FROM result r
INNER JOIN student s
ON s.StudentNo=r.StudentNo
INNER JOIN `subject` sub
ON sub.SubjectNo=r.SubjectNo;
方法二:
SELECT s.`studentName`,r.`studentResult`,sub.SubjectName
FROM result r,student s,`subject` sub
WHERE s.StudentNo=r.StudentNo AND sub.SubjectNo=r.SubjectNo;
2. 外連接 outer join
①左外連接 left join :
以左表作爲基準,右邊表來一一匹配,匹配不上的,返回左表的記錄,右表以null填充
示例:
SELECT s.studentName,r.subjectNo,r.studentResult
FROM student AS s
LEFT JOIN result AS r
ON s.studentNo = r.studentNo;
②右外連接 right join :
以右表作爲基準,左邊表來一一匹配,匹配不上的,返回右表的記錄,左表以null填充
3. 自連接(自連接的表一定要取別名)
4. 等值連接(等同於內連接)
5. 非等值連接
不同的SQL JOIN對比:
JOIN對比
操作符名稱 |
描述 |
INNER JOIN(JOIN) |
如果表中有至少一個匹配,則返回行 |
LEFT JOIN |
即使右表中沒有匹配,也從左表中返回所有的行 |
RIGHT JOIN |
即使左表中沒有匹配,也從右表中返回所有的行 |
連接查詢語句彙總示例:
#查詢參加了考試的同學信息(學號、學生姓名、科目編號、分數)
SELECT * FROM student;
SELECT * FROM result;
#思路:(1)分析需求,確定查詢的列來源於兩個表 student result,連接查詢
#(2)確定使用哪一種連接查詢? ——內連接;右連接;等值連接
1. 內連接
SELECT s.studentno,studentname,subjectno,studentresult
FROM student AS s
INNER JOIN result AS r
ON r.StudentNo=s.StudentNo
#JOIN代表就是INNER JOIN
SELECT s.studentno,studentname,subjectno,studentresult
FROM student AS s
JOIN result AS r
ON r.StudentNo=s.StudentNo
2. 左外連接(查詢了所有的同學,不考試的也查出來)
SELECT s.studentno,studentname,subjectno,studentresult
FROM student AS s
LEFT JOIN result AS r
ON r.StudentNo=s.StudentNo
3. 右外連接
SELECT s.studentno,studentname,subjectno,studentresult
FROM student AS s
RIGHT JOIN result AS r
ON r.StudentNo=s.StudentNo
#查一下缺考的同學
SELECT s.studentno,studentname,subjectno,studentresult
FROM student AS s
LEFT JOIN result AS r
ON r.StudentNo=s.StudentNo
WHERE studentresult IS NULL
#當join和where在一起用時要先寫連接查詢join後寫where
4. 等值連接(和內連接效果一樣)
SELECT s.studentno,studentname,subjectno,studentresult
FROM student AS s
INNER JOIN result AS r
WHERE r.StudentNo=s.StudentNo
5. 非等值連接(返回的記錄行數,左邊表的行數m*右邊表的行數n)
SELECT s.studentno,studentname,subjectno,studentresult
FROM student AS s
6. 連接查詢(自連接)
CREATE TABLE IF NOT EXISTS practice(
num INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
pnum INT(10) NOT NULL,
practiceName VARCHAR(50) NOT NULL,
PRIMARY KEY(num)
)
INSERT INTO practice
VALUES(2,1,"數學"),(3,1,"英語"),(4,1,"語文"),(5,2,"高數"),(6,3,"音標"),(7,4,"古文"),(8,2,"線代"),(9,3,"語法"),(10,4,"古詩");
SELECT * FROM practice AS p
#編寫sql語句,將欄目的父子關係呈現出來,(父欄目名稱、子欄目名稱)
#父欄目 子欄目
#數學 高數
#數學 線代
#英語 音標
#英語 語法
#語文 古文
#語文 古詩
#把practice表看做兩張一模一樣的表(自連接),然後將這兩張表連接查詢(自連接的表一定要取別名)
SELECT a.practiceName AS '父欄目', b.practiceName AS '子欄目'
FROM practice AS a,practice AS b
WHERE a.num=b.pnum
#思考題:查詢參加了考試的同學信息(學號,學生姓名、科目號、分數)
SELECT s.studentno,studentname,subjectno,studentresult
FROM student AS s
INNER JOIN result AS r
ON r.StudentNo=s.StudentNo
#查詢參加了考試的同學信息(學號,學生姓名、科目名稱、分數)
#連接第三個表就在前兩個表寫好之後再連第三個表
#和前後兩個表都有關係的放在中間
SELECT s.studentno,studentname,subjectname,studentresult
FROM student AS s
INNER JOIN result AS r
ON r.StudentNo=s.StudentNo
INNER JOIN `subject` AS sub
ON r.SubjectNo = sub.subjectno
#查詢學員及所屬的年級(學號 學生姓名 年級名)
SELECT studentno AS 學號,studentname AS 學生姓名,gradename AS 年級名
FROM student
INNER JOIN grade
ON student.GradeId=grade.GradeID
#查詢科目及所屬的年級(科目名稱 年級名稱)
SELECT subjectname AS 科目名稱,gradename AS 年級名稱
FROM `subject`
INNER JOIN grade
ON subject.GradeID=grade.GradeID
分組查詢GROUP BY:
SELECT [ALL | DISTINCT]
{ * | table.* | [table.field1 [as alias1] [,table.field2 [as alias2]] [,…]] }
FROM table_name [as table_alias ]
[left | out | inner join table_name2 ] #聯合查詢
[WHERE …] #指定結果需滿足的條件
[GROUP BY …] #指定結果按照哪幾個字段來分組
[HAVING …] #過濾分組的記錄必須滿足的次要條件
[ORDER BY …] #指定查詢記錄按一個或者多個條件排序
(默認是ASC:升序排列 DESC:降序排列)
[ LIMIT { [ offset,] row_count | row_count OFFSET offset }];#指定查詢的記錄從哪條至哪條
使用GROUP BY關鍵字對查詢結果分組:
- 對所有的數據進行分組統計
- 分組的依據字段可以有多個,並依次分組
- 與HAVING結合使用,進行分組後的數據篩選
示例:
#查詢不同課程的平均分,最高分,最低分
SELECT subjectno,SUM(studentresult) AS 總和,AVG(studentresult) AS 平均分,MAX(studentresult) AS 最高分,MIN(studentresult) AS 最低分
FROM result
GROUP BY subjectno;
分組之後再限制條件:
SELECT [ALL | DISTINCT]
{ * | table.* | [table.field1 [as alias1] [,table.field2 [as alias2]] [,…]] }
FROM table_name [as table_alias ]
[left | out | inner join table_name2 ] #聯合查詢
[WHERE…] #指定結果需滿足的條件
[GROUP BY…] #指定結果按照哪幾個字段來分組
[HAVING …] #過濾分組的記錄必須滿足的次要條件
[ORDER BY …] #指定查詢記錄按一個或者多個條件排序
(默認是ASC:升序排列 DWHERE ESC:降序排列)
[ LIMIT { [ offset,] row_count | row_count OFFSET offset }];#指定查詢的記錄從哪條至哪條
HAVING的使用方法和WHERE相同,但是不同點是HAVING用在分組GROUP BY之後
WHERE與HAVING對比:
- WHERE子句:用來篩選 FROM 子句中指定的操作所產生的行
- GROUP BY子句:用來分組 WHERE 子句的輸出
- HAVING子句:用來從分組的結果中篩選行
示例:
#查詢不同課程的平均分,最高分,最低分;並且取出大於80分的
SELECT subjectno,SUM(studentresult) AS 總和,AVG(studentresult) AS 平均分,MAX(studentresult) AS 最高分,MIN(studentresult) AS 最低分
FROM result
GROUP BY subjectno;
HAVING 平均分>80;
按條件排序:
SELECT [ALL | DISTINCT]
{ * | table.* | [table.field1 [as alias1] [,table.field2 [as alias2]] [,…]] }
FROM table_name [as table_alias ]
[left | out | inner join table_name2 ] #聯合查詢
[WHERE …] #指定結果需滿足的條件
[GROUP BY …] #指定結果按照哪幾個字段來分組
[HAVING …] #過濾分組的記錄必須滿足的次要條件
[ORDER BY …] #指定查詢記錄按一個或者多個條件排序
(默認是ASC:升序排列 DESC:降序排列)
[ LIMIT { [ offset,] row_count | row_count OFFSET offset }];#指定查詢的記錄從哪條至哪條
示例:
#查詢《數據庫結構-1》的所有的考試結果(學號 學生姓名 科目名稱 成績),按成績降序排列
SELECT s.studentno,studentname,subjectname,studentresult
FROM student AS s
INNER JOIN result AS r
ON r.StudentNo=s.StudentNo
INNER JOIN `subject` AS sub
ON r.SubjectNo = sub.subjectno
WHERE subjectname='數據庫結構-1'
ORDER BY studentresult ASC #默認ASC升序
ORDER BY studentresult DESC #DESC降序排列
ORDER BY studentresult DESC,studentno ASC #成績降序排列,學號升序排列
#常見錯誤:ORDER BY studentresult,studentno DESC (此時的排序規則是按照成績:studentresult升序排列,之後按照學號studentno降序排列)
分頁操作:
分頁必須會,必會用到
優點:提高用戶體驗、增加網絡傳輸速度、緩解查詢壓力
SELECT [ALL | DISTINCT]
{ * | table.* | [table.field1 [as alias1] [,table.field2 [as alias2]] [,…]] }
FROM table_name [as table_alias ]
[left | out | inner join table_name2 ] #聯合查詢
[WHERE …] #指定結果需滿足的條件
[GROUP BY …] #指定結果按照哪幾個字段來分組
[HAVING …] #過濾分組的記錄必須滿足的次要條件
[ORDER BY …] #指定查詢記錄按一個或者多個條件排序
[ LIMIT { [ offset,] row_count | row_count OFFSET offset }];#指定查詢的記錄從哪條至哪條
LIMIT 當頁的起始序號(但是不包含這個序號),顯示幾條
注:
- 數據庫不同分頁語句也不一樣
- Limit 0,5:這種寫法是最常用的寫法等同於limit 5 offset 0;
示例:
#查詢《數據庫結構-1》的所有的考試結果(學號 學生姓名 科目名稱 成績),按成績降序排列、
#結果每頁顯示5條
SELECT s.studentno,studentname,subjectname,studentresult
FROM student AS s
INNER JOIN result AS r
ON r.StudentNo=s.StudentNo
INNER JOIN `subject` AS sub
ON r.SubjectNo = sub.subjectno
WHERE subjectname='數據庫結構-1'
ORDER BY studentresult DESC
#Limit 0,5; #第一個數字代表從哪條記錄開始(pageno-1)*pagesize(起始行,從0開始) 第二個數字代表要顯示幾條pagesize
#limit 5,5; #查詢第二頁
#limit 10,5; #第三頁
#limit 15,5; #第四頁
#limit(pageno-1)*pagesize,pagesize 【(當前頁碼-1)*頁容量,頁容量】
注意事項:
記住語法;分析要求;逐條書寫;注意順序
總示例:
#查詢1. 《JAVA第一學年》課程成績2. 前10名且3. 分數大於80的學生信息(學號、姓名、課程名、分數)
SELECT s.studentno,studentname,subjectname,studentresult
FROM student AS s
INNER JOIN result AS r
ON r.StudentNo=s.StudentNo
INNER JOIN `subject` AS sub
ON r.SubjectNo = sub.subjectno
WHERE subjectname='JAVA第一學年' AND studentresult>80
ORDER BY studentresult DESC
LIMIT 0,10;
子查詢:
什麼是子查詢?
在查詢語句中的WHERE條件子句中,又嵌套了另外一個查詢語句,子查詢是一個嵌套在 SELECT、INSERT、UPDATE 或 DELETE 語句或其他子查詢中的查詢
注:
嵌套查詢可由多個子查詢組成,求解的方式是由裏及外;
先執行子查詢,返回所有來自子查詢的結果,再執行外圍的父查詢,返回查詢的最終結果;
子查詢返回的結果一般都是集合,故而建議使用IN關鍵字;
子查詢在WHERE語句中的一般用法:
SELECT … FROM 表1 WHERE 字段1 比較運算符(子查詢)
示例:
IN子查詢:
常用IN替換等於(=)的子查詢
IN後面的子查詢可以返回多條記錄
示例:查詢參加“Logic Java”課程最近一次考試的在讀學生名單:
實現步驟:
1. 獲得 “Logic Java”課程的課程編號
SELECT `subjectNo` FROM `subject`
WHERE `subjectName`='Logic Java';
2. 獲得 “Logic Java”課程的課程編號
SELECT MAX(`examDate`) FROM `result` WHERE `subjectNo`= (
SELECT `subjectNo` FROM `subject`
WHERE `subjectName`='Logic Java' );
3. 根據課程編號和最近一次的考試日期查詢出在讀學生信息
連接查詢,子查詢示例彙總:
示例一:
#查詢《數據結構-1》的所有考試結果(學號、科目編號、分數),並按成績降序排列
#方法一:使用連接查詢
SELECT studentno,r.SubjectNo,studentresult
FROM result AS r
INNER JOIN `subject` sub
ON r.SubjectNo=sub.SubjectNo
WHERE subjectname='數據庫結構-1'
ORDER BY studentresult DESC;
#方法二:使用子查詢
SELECT studentno,r.SubjectNo,studentresult
FROM result AS r
WHERE subjectno=(SELECT subjectno FROM `subject` WHERE subjectname='C語言-1')
ORDER BY studentresult DESC;
#這就是子查詢的寫法,外面的select叫做父查詢,裏面的select叫做子查詢,他們兩個是嵌套的關係
#查詢順序是由裏向外的,會先執行裏面的查詢吧結果放在那裏,再執行外面的查詢
#並不是所有外查詢和內查詢之間的位置是等於號
示例二:
#查詢課程爲《高等數學-2》且分數不小於80份的學生的學號和姓名
#方法一:使用連接查詢
SELECT r.studentno,studentname
FROM student AS s
INNER JOIN result AS r
ON s.StudentNo=r.StudentNo
INNER JOIN `subject`sub
ON r.SubjectNo=sub.SubjectNo
WHERE subjectname='高等數學-2' AND StudentResult>=80
#方法二:使用連接查詢+子查詢(將需求拆分、細化、逐步完善SQL語句)
#1. 分數不小於80份的學生的學號和姓名
SELECT studentno,studentname
FROM student AS s
INNER JOIN result AS r
ON s.StudentNo=r.SubjectNo
WHERE studentresult>=80
#2. 在上面SQL基礎上,添加需求:查詢課程爲《高等數學-2》的成績
AND subjectno=(SELECT subjectno FROM `subject` WHERE subjectname='高等數學-2')
#方法三:使用子查詢
SELECT studentno,studentname FROM student WHERE studentno IN(1,2,3,4,……) #會查出多個學生對多個學生比較,當返回值有多個的時候就要用in
SELECT studentno FROM result WHERE studentresult>=80 AND subjectno=2 # 1 2 3 4 ……
SELECT subjectno FROM `subject` WHERE subjectname='高等數學-2' #2
#分步寫簡單SQL語句,然後將其嵌套起來
SELECT studentno,studentname FROM student WHERE studentno IN(
SELECT studentno FROM result WHERE studentresult>=80 AND subjectno=(
SELECT subjectno FROM `subject` WHERE subjectname='高等數學-2'))
示例三:
#查詢《C語言-1》的前五名學生的成績信息:學號、姓名、分數
#方法一:使用連接查詢
SELECT r.studentno,studentname,studentresult
FROM student AS s
INNER JOIN result AS r
ON s.StudentNo=r.StudentNo
INNER JOIN `subject` AS sub
ON sub.SubjectNo=r.SubjectNo
WHERE subjectname='C語言-1'
ORDER BY studentresult DESC
LIMIT 0,5;
#方法二:使用連接查詢+子查詢(將需求拆分、細化、逐步完善SQL語句)
#1. 查詢出學號和姓名
SELECT r.studentno,studentname,studentresult
FROM student AS s
INNER JOIN result AS r
ON s.StudentNo=r.StudentNo
#2. 在上面SQL基礎上,添加需求:查詢課程爲《C語言-1》的成績
WHERE subjectno=(SELECT subjectno FROM `subject` WHERE subjectname='C語言-1')
ORDER BY studentresult DESC
LIMIT 0,5;
示例四:
#使用子查詢實現,查詢郭靖同學所在的年級名稱
SELECT gradename FROM grade WHERE gradeid=(
SELECT gradeid FROM student WHERE studentname='郭靖')
注:
- 任何允許使用表達式的地方都可以使用子查詢
- 嵌套在父查詢SELECT語句的子查詢可包括
SELECT子句;FROM子句;WHERE子句;GROUP BY子句;HAVING子句
其中:WHERE、GROUP BY、HAVING是可選子句,根據業務需求決定
只出現在子查詢中而沒有出現在父查詢中的列不能包含在輸出列中
MySQL函數:
1. 數學函數
函數名 |
作用 |
舉例 |
ABS(x) |
返回數值x的絕對值 |
SELECT ABS(-3) 返回:3 |
CEILING(x) |
返回大於或等於數值x的最小整數 |
SELECT CEIL(2.3) 返回:3 |
FLOOR(x) |
返回小於或等於數值x的最大整數 |
SELECT FLOOR(2.3) 返回:2 |
ROUND() |
四捨五入 |
SELECT ROUND(5.3) 返回:5 |
RAND() |
返回0~1間的隨機數 |
SELECT RAND() 返回:0.5525468583708134 |
RAND(10) |
以某個數作爲種子,返回重複隨機數 |
SELECT RAND(10) 返回:重複隨機數 |
SIGN(0) |
符號函數,正數1;負數-1 0返回0 |
SELECT SIGN(0) 返回:0 |
2. 字符串函數
函數名 |
作用 |
舉例 |
CHAR_LENGTH(str) |
計算字符數 |
SELECT CHAR_LENGTH('學習數據庫'); #返回:5 |
CONCAT(str1,str1...strn) |
字符串連接 |
SELECT CONCAT('My','S','QL'); 返回:MySQL |
INSERT(str,pos,len,newstr) |
字符串替換 |
SELECT INSERT('這是SQL Server數據庫',3,10,'MySQL'); 返回:這是MySQL數據庫 |
LOWER(str) |
將字符串轉爲小寫 |
SELECT LOWER('MySQL'); 返回:mysql |
UPPER(str) |
將字符串轉爲大寫 |
SELECT UPPER('MySQL'); 返回:MYSQL |
LEFT(str,len) |
從左面截3個字符 |
SELECT LEFT('課工場歡迎你',3); 返回:課工場 |
RIGHT(str,len) |
從右面截3個字符 |
SELECT LEFT('課工場歡迎你',3); 返回:歡迎你 |
REPLACE(str1,str2,str3) |
替換字符 |
SELECT REPLACE('課工場歡迎你','你','你們'); 返回:課工場歡迎你們 |
REVERSE(str) |
反轉 |
SELECT REVERSE('課工場歡迎你'); 返回:你迎歡場工課 |
SUBSTRING(str,num,len) |
字符串截取 |
SELECT SUBSTRING('JavaMySQLOracle',5,5); 返回:MySQL |
3. 日期和時間函數
函數名 |
作用 |
舉例(結果與當前時間有關) |
CURRENT_DATE() |
獲取當前日期 |
SELECT CURRENT_DATE() 返回:2018-09-10 |
CURDATE() |
獲取當前日期 |
SELECT CURDATE(); 返回:2016-08-08 |
CURTIME() |
獲取當前時間 |
SELECT CURTIME(); 返回:19:19:26 |
NOW() |
獲取當前日期和時間 |
SELECT NOW(); 返回:2016-08-08 19:19:26 |
LOCALTIME() |
獲取當前日期和時間 |
SELECT LOCALTIME(); 返回:2016-08-08 19:19:26 |
SYSDATE() |
獲取當前日期和時間 |
SELECT SYSDATE (); 返回:2016-08-08 19:19:26 |
WEEK(date) |
返回日期date爲一年中的第幾周 |
SELECT WEEK(NOW()); 返回:26 |
YEAR(date) |
返回日期date的年份 |
SELECT YEAR(NOW()); 返回:2016 |
HOUR(time) |
返回時間time的小時值 |
SELECT HOUR(NOW()); 返回:9 |
MINUTE(time) |
返回時間time的分鐘值 |
SELECT MINUTE(NOW()); 返回:43 |
DATEDIFF(date1,date2) |
返回日期參數date1和date2之間相隔的天數 |
SELECT DATEDIFF(NOW(),'2008-8-8'); 返回:2881 |
ADDDATE(date,n) |
計算日期參數date加上n天后的日期 |
SELECT ADDDATE(NOW(),5); 返回:2016-09-02 09:37:07 |
4. 系統信息函數
函數名 |
作用 |
舉例 |
VERSION() |
獲取系統版本 |
SELECT VERSION() 返回:5.5.40 |
USER() |
獲取用戶 |
SELECT USER() 返回:root@localhost |
6. 聚合函數
函數名 |
作用 |
舉例 |
AVG() |
通常爲數值字段或表達列作統計,返回一列的平均值 |
SELECT AVG(studentresult) AS 平均分 FROM result |
COUNT() |
返回滿足SELECT條件的記錄總和數,如SELECT COUNT(*). . |
SELECT COUNT(email) FROM student SELECT COUNT(*) FROM student SELECT COUNT(1) FROM student |
MAX() |
可以爲數值字段、字符字段或表達式列作統計,返回最大的值 |
SELECT MAX(studentresult) AS 最高分 FROM result |
MIN() |
可以爲數值字段、字符字段或表達式列作統計,返回最小的值 |
SELECT MIN(studentresult) AS 最低分 FROM result |
SUM() |
返回數字字段或表達式列作統計,返回一列的總和 |
SELECT SUM(studentresult) AS 總和 FROM result |
示例:
#查詢不同課程的平均分,最高分,最低分
SELECT subjectname,SUM(studentresult) AS 總和,AVG(studentresult) AS 平均分,MAX(studentresult) AS 最高分,MIN(studentresult) AS 最低分
FROM result AS r
INNER JOIN `subject` AS sub
ON r.subjectno=sub.subjectno
GROUP BY r.subjectno
HAVING 平均分>80
ORDER BY 平均分 DESC
LIMIT 0,4;
注:
寫數據庫時候一定要注意報錯時錯誤碼後面的提示;明白各種錯誤的比對,記住解決方案