1. 程式人生 > 資料庫 >朝花夕拾 Mysql筆記2

朝花夕拾 Mysql筆記2

朝花夕拾 Mysql筆記2

歡迎掃碼關注微信公眾號"野心與家"回覆"12.11MySQL2"獲取原始檔

4.1 簡單查詢

>4.1.1 select 語句

語法 //順序不能顛倒

mysql> > select [distinct] * |欄位名1,欄位名2,欄位名3,...
	>	from 表名
	>	[where 條件表示式1]
	>	[group by 欄位名 [having條件表示式2]]
	>	[order by 欄位名 [asc|desc]]
	>	[limit [offset] 記錄數]

>4.1.2 查詢所有欄位

> 1.在select語句中指定所有欄位
語法:select 欄位名1,欄位名2,...from 表名
> 2.在select語句中使用星號(*)萬用字元代替所有欄位
select * from 表名

>4.1.3 查詢指定欄位

語法: select 欄位名1,欄位名2,...from 表名;

4.2 按條件查詢

>4.2.1帶關係運算符查詢

where 子句中指定查詢條件對資料進行過濾

語法:select 欄位名1,欄位名2,... from 表名 where 條件表示式

>4.2.2 帶in關鍵字的查詢

in關鍵字用於判斷某個欄位的值是否在指定集合中

語法:select * |欄位名1,欄位名2,... from 表名 where 欄位名[not] in (元素1,元素2)
	"元素1,元素2"表示集合中的元素,即指定的條件範圍
	not 為可選引數,使用not表示查詢不在in關鍵字指定集合範圍的記錄
例如:查詢student表中ID值為1,2,3的記錄
mysql> select id,grade,name,grade from student where id in(1,2,3);

>4.2.3帶between and 關鍵字查詢

between and 用於判斷某個字元的值是否在指定的範圍之內,如果欄位的值在指定的範圍內,則滿足條件

select * |{欄位名1,欄位名2,...} from 表名 where 欄位名 [not] between 值1 and 值2
例如: 查詢student表中id值在2~5之間的學生姓名
mysql> select id,name from student where id between 2 and 5;

>4.2.4 空值查詢

在資料表中,某些列的值可能為空值(null),空值不同於0,也不同於空字串

在mysql中,使用is null關鍵字來判斷是否為空值

語法:select * |字元段1,字元段2,... from 表名 where 欄位名 is [not] null;
例如:查詢Student表中gender為空值的記錄
mysql> select id,name,grade,gender from student where gender is null;

>4.2.5 帶distinct關鍵詞的查詢

很多表中某些欄位的資料存在重複的值,使用distinct過濾重複記錄的欄位

例如:在student表中查詢gender(性別)欄位的值,查詢記錄不能重複;
mysql> select distinct gender from student;

distinct關鍵字作用於多個欄位,如果欄位名1欄位名2裡的值都相同才被認為是重複記錄

語法:select distinct 欄位名1,欄位名2,...from 表名;

>4.2.6 帶like關鍵字的查詢

使用關係運算符"="可以判斷兩個字串是否相等,但有些需要是對字串進行模糊查詢

select * | {字元段1,字元段2,...}
from 表名
where 欄位名 [not] like '匹配字串';
1. 百分號(%) 萬用字元

作用 : 匹配任意長度的字串 ,包括空字串

例1: 查詢student表中name欄位值以字元"s"開頭的學生 id
mysql> select id, name from student where name like "s%" ;

例2:查詢student表中name欄位值以字元"w"開頭,以字元"g"結束的學生 id
mysql> select id, name from student where name like "w%g" ;

例3:查詢student表中name欄位值包括字元"y"的學生 id;
mysql> select id, name from student where name like "%y%" ;
2. 下劃線(_) 萬用字元

作用 : 下劃線萬用字元只能匹配單個字元,如果需要匹配多個則需要使用多個下劃線

例1: 查詢student表中name欄位值以字串"wu"開始, 以字串"ong"結尾,並且兩個字串之間只有一個字元的記錄
mysql> select * from student where name like "wu_ong";

例2: 查詢student表中name字元值包括7個字元, 並且以字串"ing"結尾的記錄
mysql> select * from student where name like "_______ing";
3.使用百分號和下劃線萬用字元進行查詢操作

作用 : 通過右斜線( " \ " )對百分號和下劃線進行轉義

例如 : "%"匹配百分號字元值 , " \ _ "匹配下劃線字元值

例如: 查詢student表中name欄位值包括"%"的記錄;
mysql> insert into student (name,grade,gender)
	-> values ('sun%er',95,'男');
	
mysql> select * from student where name like "%\%%";

>4.2.7 帶and關鍵字的多條件查詢

and關鍵字連線兩個或以上查詢條件

例如:select * from 表名 where 條件表示式1 and 條件表示式2 [...and 條件表示式n]
查詢student表中id欄位值在1.2.3.4之中,name字元值以字串'ng'結尾,並且grade欄位值小於80的記錄
mysql> select id,name,grader,gender
	-> from student
	-> where id in(1,2,3,4) and name like '%ng' and grade <80;

>4.2.8 帶or關鍵字的多條件查詢

or關鍵字滿足一個,可以連線兩個或多個查詢條件

例如:查詢student表中滿足條件name欄位值以字元'h'結束,或者gender字元值為'女',或者grade欄位值為100的記錄
mysql> select id,name,grade,gender
	-> from student
	-> where name like '%h' or gender='女' or grade=100;

注意:or和and可以一起使用, and優先順序高於or

例如:查詢student表中student字元值為'女'或者gender字元值為'男',並且gender欄位值為100的學生姓名
mysql> select name,grade,gender
	-> from student
	-> where gender='女' or gender ='男' and grade=100;

4.3 高階查詢

>4.3.1 聚合函式

>1.count()函式
COUNT()函式用來統計記錄的條數,其語法格式如下所示:
SELECT COUNT(*) FROM 表名;
例如: 查詢student表中一共有多少條記錄
mysql> select count(*) from student;
>2.sum()函式
SUM()是求和函式,用於求出表中某個欄位所有值的總和,其語法格式如下:
SELECT SUM(欄位名) FROM 表名
例如:求出student表中grade欄位的總和
mysql> select sum(grade) from student7
>3.avg()函式
AVG()函式用於求出某個欄位所有值的平均值其語法格式如下所示:
SELECT AVG(欄位名) FROM student;
例如:求出student表中grade欄位的平均值
>select avg(grade) from student
>4.max()函式
MAX()函式是求最大值的函式,用於求出某個欄位的最大值,其語法格式如下所示:
SELECT MAX(grade) FROM student;
例如:求出student表中grade欄位的最大值
>select max(grade) from student
>5.min()函式
MIN()函式是求最小值的函式,用於求出某個欄位的最小值,其語法格式如下所示:
SELECT MIN(grade) FROM student;
例如:求出student表中grade欄位的最小值
>select min(grade) from student

>4.3.2 對查詢結果排序

從表中查詢出來的資料可能是無序的,或者排列順序不是使用者期望的,為了使查詢結果滿足使用者的要求,可以使用order by

對查詢結果進行排序,語法格式如下:
使用 ORDER BY對查詢結果進行排序其語法格式如下所示:
SELECT欄位名1, 欄位名2, FROM 表名
ORDER BY欄位名1 [ASC|DESC],欄位名2 [ASC|DESC] /*asc:升序,從小到大,desc:倒敘,從大到小*/
例2:查詢student表中的所有記錄,按照gender欄位的升序和grade欄位的降序進行排序:
mysql> select * from student
	-> order by gender asc, grade desc;

==注意:==在按照指定欄位進行升序排列時,如果某條記錄的欄位值為NULL,則這條記錄會在第一條顯示,這是因為NULL值可以被認為是最小值

> 4.3.3 分組查詢

>1.單獨使用group by 分組

單獨使用group by 關鍵詞,查詢的是每個分組的一條記錄

例如:查詢student表中的記錄,按照gender欄位值進行分組
select * from student group by gender;

查詢結果是按照gender欄位中的不同值進行分類的,查詢結果只顯示每個分組
>2.group by和聚合函式一起使用

gruop by 和聚合函式一起使用可以統計出某個或者某些欄位在一個分組中的最大值,最小值,平均值等

例如:將student表中gender欄位值進行分組查詢,計算出每個分組中各有多少名學生
select count(*),gender from student group by gender; 
例如:將student表中gender欄位值進行分組查詢,計算出每個分組的總成績,平均成績,最高分,最低分
select sum(grade),avg(grade),max(grade),min(grade),genter from student3 group by genter;
>3. group by 和 having關鍵詞一起使用

having關鍵字和 where關鍵字的作用相同,都設定條件表示式對查詢結果進行過濾,兩者區別在於,

having關鍵字後可以跟聚合函式,而where 關鍵字不能

例如:將student表中按照gender欄位進行分組查詢,查詢grade欄位值之和小於300的分組
select student sum(grade),gender from student group by gender having sum(grade)<300 

>4.3.4 使用limit限制查詢結果的數量

查詢資料時,可能會返回很多條記錄,而使用者需要的記錄可能只是其中的一條或者幾條,比如實現分頁功能,每頁顯示10行資訊,每次查詢都需要查出10條記錄

格式:select 欄位名1,欄位名2,...
	from 表名
	limit [offset,] 記錄數  //limit後可以跟兩個引數,第一個引數offset表示偏移量,如果為0則從查詢結果的第一條開始記錄,偏移量為1則從查詢結果中的第二條記錄開始,以此類推;offset為可選值,如果不指定其預設值為0.第二個引數"記錄數"表示返回查詢記錄的條數;
例(1):查詢Student表中的前四條記錄
select * from student limit 4;	//沒有指定返回記錄的偏移量,只指定了查詢記錄的條數4,因此返回結果從第一條開始,一共返回4條記錄;
例(2):查詢student表中grade欄位值從第五位到第八位的學生(從高到低)
select * from student group desc limit 4,4

limit後面第一個引數表示偏移量位4,即從第五條開始查詢,第二個引數表示一共返回4條記錄,即從第五位到第8為學生

>4.3.5 函式(列表)

函式名稱作用
ABS(x)返回x的絕對值
SQRT(x)返回x的非負2次方根
MOD(xy)返回x被y除後的餘數
CEILING(x)返回x的絕對值
FLOOR(z)返回x的絕對值
ROUND(x,y)返回x的絕對值
TRUNCATE(x)返回x的絕對值
SIGN(x)2返回x的絕對值

4.4 為表和欄位取別名

> 4.4.1 為表取別名

在查詢操作時,如果表名很長使用起來就不太方便,這時可以為表取一個別名,用這個別名來代替表的名稱;

語法:	select * from 表名 [as] 別名;	as關鍵字用於指定表名的別名,它可以省略不寫;
例如: 為student表起一個別名 s,並查詢student表中gender欄位值為'女'的記錄
select * from student as s where s.gender='女';	
student as s表示student表的別名為s
s.gender 表示student表中的gender欄位;

> 4.4.2 為欄位取別名

為了讓顯示查詢結果更加直觀,可以為欄位取一個別名

select 欄位名 [as] 別名 [,欄位名 [as] 別名,...] from 表名;
例如:查詢student表中的所有記錄的name和grade欄位值,併為這兩個欄位名起別名stu_name和stu_genter;
select * from name as stu_name, grader as stu_genter from student;

5.1 外來鍵

> 5.1.1 什麼是外來鍵

外來鍵是指引用另一個表中的一列或多列,==被引用的列應該具有主鍵約束或唯一性約束.==外來鍵用來建立和加強兩個表資料之間的連線

引入外來鍵後,外來鍵列只能插入參照列存在的值,參照列被參照的值不能被刪除,這就確保了資料的參照完整性

建立兩個表,一個班級表(grade),一個學生表(student)

create table grade(
	id int(4) not null primary key,
	name varchar(36)
);

create table student(
	sid int(4) not null primary key,
	sname varchar(36),
	gid int(4) not null
);

學生表(student)中的gid 是學生所在的班級id,是引入了班級表(grade) 中的主鍵id,那麼gid就可以作為表student的主鍵…被引用的表,即表grade是主表;引用外來鍵的表,即表student是從表,兩個表是主從關係.

表student用gid可以連線表grade中的資訊

>5.1.2 為表中新增外來鍵約束

語法: alter table 表名 add constraint FK_ID foreign key(外來鍵欄位名) references 主表表名(主鍵欄位名);
語句: alter table student add constraint FK_ID foreign key(gid) references grade(id);

>5.1.3 刪除外來鍵約束

在實際開發中,根據業務邏輯的需求,需要解除兩個表的關聯關係時, 就需要刪除外來鍵約束

語法: alter table 表名 drop foreign key 外來鍵名;

接下來,將表中student表的外來鍵約束刪除

alter table student drop foreign key FK_ID; 

5.2 操作關聯表

>5.2.1 關聯關係

1.多對一 (外來鍵定義在多端)

一個部門可以有多個員工,而一個員工不能屬於多個部門。
在多對一的表關係中,應該將外來鍵建在多的一方

2.多對多 (需定義中間表)

一個老師可以教多個學生,同時一個學生可以上多個老師的課程。
為了實現資料表多對多的關係,需要定義一張第三方中間表,該表儲存兩個關係表的外來鍵。

3.一對一 (從表依賴主表)

一對一的對應關係中,需要分清主從關係,通常在從表中建立外來鍵

>5.2.2 新增資料

在開發中,最常見的關聯關係就是多對一關係

為表student和表grade中新增外來鍵約束來建立兩個表的關聯關係
alter table student add constraint FK_ID foreign key(gid) references grade (id);

>5.2.3 刪除資料

由於grade表與student表之間具有關聯關係 , 參照列被參照的值不能被刪除的,再刪除軟體二班時需要刪除軟體二班的所有學生

delete from student where sname='王紅';
delete from student where sname='李強';
delete * from grade where id=2;

5.3 連線查詢

> 5.3.1交叉連線

交叉連線返回的結果是被連線的兩個表中所有資料行的笛卡爾積即行數的乘積

例如:department表中有4個部門,employee表中有4個員工,那麼交叉連線的結果就有4X4=16條資料

語法: select *from 表1,表2;
	 或select * from 表1 cross join 表2;
> 5.3.2 內連線

內連線(INNER JOIN)又稱簡單連線或自然連線,內連線使用比較運算子對兩個表中的資料進行比較,列出與連線條件匹配的資料行,組合成新的記錄

簡單連線或自然連線,返回的結果是兩個表中一一對應的資料,只有滿足條件的資料才顯示

語法:select 查詢欄位 from 表1[inner] join 表2 on 表1.關係欄位= 表2.關係欄位
例如: 在department表和employee表之間使用內連線查詢;
select employee.name,department.dname from department inner join employee on department.did=employee.did;	//只有department.did和employee.did相等的才輸出
使用where條件語句來實現同樣的功能;
例如:在department表和employee表之間使用where:
select employee.name, department.dname from department,employee where department,did=employee.did;

注意:where子句的查詢結果與使用inner join的查詢結果是一致的,雖然結果相同,但inner join 是內連線語句,where是條件判斷語句,在where語句後可以新增其他條件,而inner join語句不可以;

如果在一個連線查詢中,涉及的兩個表是同一個表,這種查詢稱為自連線查詢,指的是相互連線的表在物理上為同一個表,但邏輯上分為兩個表

查詢部門為2的員工的姓名和年齡;
select department.did,employee.name,employee.age from department join employee on department.did=employee.did where department.did=2;
或
select department.did,employee.name,employee.age from department,employee where department.did=employee.did and department.did=2;
查詢姓名為王紅所在的部門編號和部門名稱
select employee.name,department.did,department.dname from department,employee where department.did=employee.did and employee.name='王紅';

自連線:

例如:在department表和employee表之間使用自連線查詢王紅所在的部門有哪些員工;
select p1.* from employee p1 inner join employee p2 on p1.did=p2.did where p2.name='王紅';	/*p1 p2為別名*/
或select p1.* from employee p1,employee p2 where p1.did=p2.did and p2.name='王紅';/*where方法*/
> 5.3.3 外連線

外連線分為左連線和有連線

左連線的結果包括LEFT JOIN子句中指定的左表的所有記錄,和所有滿足連線條件的記錄。如果左表的某條記錄在右表中不存在,則在右表中顯示為空 ;

右連線與左連線正好相反,返回右表中所有指定的記錄和所有滿足連線條件的記錄。如果右表的某條記錄在左表中沒有匹配,則左表將返回空值 ;

做外連結:左表中的所有記錄以及內連線的記錄(放在前面的是左表)

右外連線:右表中的所有記錄以及內連線的記錄

語法: SELECT 所查欄位 FROM 表1 LEFT|RIGHT [OUTER] JOIN 表2 
	ON 表1.關係欄位 = 表2.關係欄位 WHERE 條件
	
	select * from 表1,表2 where表1.關係欄位=表2.關係欄位 and 其他條件
>全外連線查詢

在外連線的基礎上,增加左邊表有,右邊表沒有的記錄,以及右邊表有左邊表沒有的記錄

語法: select * from 表1 full jion 表二 on 表一.關係欄位=表二.關係欄位;
	select * from dep full jion emp on dep.did=em.did;

>5.3.4 複合條件查詢

5.4 子查詢

>5.4.1 帶IN關鍵字的子查詢

使用in關鍵字進行子查詢時,內層查詢語句僅返回一個數列值,這個數列值中的值將供外層查詢語句進行比較操作

例如:查詢存在年齡為20歲的員工的部門
select * from department where did in(select did from employee where age=20);
或											           //子查詢方法
select department.did,department.dname from department join employee on department.did=employee.did where employee.age=20;		//內連線方法
或
select department.did,department.dname from department,employee where department.did=employee.did and employee.age=20;	 	  //where方法
>5.4.2 帶exists關鍵字的子查詢

exists關鍵字後面的引數可以是任意一個子查詢,這個子查詢的作用相當於測試,他不產生任何資料,只返回true或false,當返回值為true時,外層查詢才會執行

例如:查詢employee表中是否存在年齡大於21歲的員工,如果存在,則查詢department表中的所有記錄
select * from department where exists(select did from employee where age>21);
> 5.4.3 帶any關鍵字的子查詢

any關鍵字表示滿足其中任意一個條件,它允許建立一個表示式對子查詢的返回值列表進行比較

例如:
select * from department where did>any(select did from employee);//列出只要大於employee.did任意一個數
>5.4.4 帶all關鍵字的子查詢
例如:
select * from department where did>all(select did from employee);/列出大於employee.did所有的數
>5.4.5 帶比較運算子的子查詢

比較運算子 > , < , = , >= , <= , ! =

例如:使用比較運算子的子查詢,查詢趙四是哪個部門的員工
select * from department where did=(select did from employee where name ="趙四");

6.1 事務管理

> 6.1.1 事務的概念

所謂的事務就是針對資料庫的一組操作,它可以由一條或多條SQL語句組成,同一個事務的操作具備同步的特點,即事務中的語句要麼都執行,要麼都不執行

開啟事務的語法: start transaction

上述語句用於開啟事務,事務開啟之後就可以執行SQL語句,SQL語句執行成功後,需使用相對應語句提交事務,語法如下:

提交事務的語法: commit

在操作一個事務時,如果發現當前事務中的操作是不合理的,此時只要還沒有提交事務,就可以通過回滾來取消當前事務

事務回滾語句: rollback