1.表與表之間的關(guān)系
一對一:用戶表和身份信息表,用戶表是主表
例如:男人表 、女人表
??create?table?man(? ???mid?int?primary?key??auto_increment, ????????mname?varchar(32), ????????wid?int?unique ????);
?create?table?woman( ????????wid??int?primary?key??auto_increment, ????????wname?varchar(32) ????);
一對多:最常見的表關(guān)系,用戶表和訂單表
例如:員工表、部門表
?create?table?emp( ????????????empno?int?primary?key??auto_increment, ????????????ename?varchar(32), ????????????deptno?int ????????);
?create?table?dept( ????????????deptno?int?primary?key??auto_increment, ????????????dname?varchar(32) ????????);
多對多:例如學(xué)生表和課程表,通常情況都是將多對多的關(guān)系拆分為一對多或者多對一的關(guān)系。
create?table?student(????????????sid??int?primary?key??auto_increment, ????????????sname?varchar(32) ????????);
insert?into?student?(sname)?values?('大拿');????? insert?into?student?(sname)?values?('唐嫣'); insert?into?student?(sname)?values?('王健林');
?create?table?course( ????????????cid?int?primary?key??auto_increment, ????????????cname?varchar(32) ????????);
insert?into?course?(cname)?values?('語文');???? insert?into?course?(cname)?values?('數(shù)學(xué)');???? insert?into?course?(cname)?values?('英語');???? insert?into?course?(cname)?values?('化學(xué)');
create?table?s_c( ???????cid?int,????????sid?int ???);
?insert?into?s_c?(sid,cid)?values?(1,1);???? ?insert?into?s_c?(sid,cid)?values?(1,2);???? ?insert?into?s_c?(sid,cid)?values?(1,3);???? ?insert?into?s_c?(sid,cid)?values?(1,4);???? ?insert?into?s_c?(sid,cid)?values?(2,2);???? ?insert?into?s_c?(sid,cid)?values?(2,4);???? ?insert?into?s_c?(sid,cid)?values?(3,1);???? ?insert?into?s_c?(sid,cid)?values?(3,3);
2.為什么要使用多張表
避免出現(xiàn)大量的數(shù)據(jù)的冗余。
并不是表拆的越多就越好,根據(jù)實際情況進行拆分。
3.概念
同時查詢多張表
4.分類
合并查詢
? ?union ,union all
? ?合并結(jié)果集,就是把兩個select語句的查詢結(jié)果合并到一起。(相當(dāng)于并集)
? ?合并的兩個結(jié)果,列數(shù)和列的順序,類需要一致
create?table?emp( ???????empno?int?primary?key??auto_increment, ???????ename?varchar(32) ???);
create?table?dept( ????????deptno?int?primary?key??auto_increment, ????????dname?varchar(32) ????);
select?*?from?emp??union?select?*?from?dept;???? select?*?from?emp??union?all?select?*?from?dept;
連接查詢
員工表
??create?table?emp( ????????????empno?int?primary?key?auto_increment,?#?員工編號 ????????????ename?varchar(32),??#員工姓名 ????????????job?varchar(32),????????#員工職位 ????????????mgr??int,???????????????????????#上級編號 ????????????hiredate?date,??????????#入職時間 ????????????sal?double,?????????????????#薪水 ????????????comm?double,????????????????#獎金 ????????????deptno?int??????????????????#所屬部門 ????????);
?部門表
?create?table?dept( ????????????deptno?int?primary?key?auto_increment,??#部門編號 ????????????dname?varchar(32),??????#部門名稱 ????????????loc?varchar(32)?????????????#部門地址 ????????);
內(nèi)連接: inner join….on ?、 join 、 ,
? ? ? ?inner join 是比較運算符,只返回符合條件的行
例如:
select?*?from?emp?inner?join??dept??on?emp.deptno=dept.deptno;???????? select?*?from?emp?e?,dept?d?where?e.deptno?=?d.deptno;???????? select?*?from?emp?e?join?dept?d?where?e.deptno?=?d.deptno;
外連接:
? ? ? ?左外連接:LEFT OUTER JOIN | left join … on
? ? ? ? ? ?代表查詢,左邊行的全部,右邊沒有則null
select?*?from?emp?e?LEFT?OUTER?JOIN??dept?d?ON?e.deptno?=?d.deptno;
右外連接: right join … on 或者 ?right outer join …. on
? ? ? ? ? ?右連接包含right join 右表所有的行,如果左表中某行在右表沒有匹配,則結(jié)果中對應(yīng)的左表的部門全部為空(null)
?select?*?from?emp?e?right?OUTER?JOIN??dept?d?ON?e.deptno?=?d.deptno;
自連接:
? ? ? ?自連接就是說,在同一個數(shù)據(jù)表中,看作是兩個表,表示查找每個人的領(lǐng)導(dǎo),如果沒有領(lǐng)導(dǎo),則顯示無領(lǐng)導(dǎo)
????? ?把一張表看作成兩張表,一張員工表,一張領(lǐng)導(dǎo)表,都是emp表
select?e.ename,el.ename?from?emp?e?left?join?emp?el?on?e.mgr?=?el.empno;
自然連接:natural join (join)| ? natural ?left join(同 left join) | natural right join (同 right join)
? ? ? ?自然連接會自動判斷,以兩個表中相同的字段為連接條件,返回查詢結(jié)果。
select?*?from?emp?natural?join?dept;??????? select?*?from?emp?NATURAL?left?join?dept;???????? select?*?from?emp?NATURAL?right?join?dept;
注意:內(nèi)連接不寫連接條件會出現(xiàn)笛卡爾積的結(jié)果,應(yīng)該避免這種情況,而外連接不寫連接條件會報錯。
子查詢(ANY子查詢、IN子查詢、SOME子查詢、ALL子查詢)
? ?子查詢解決的問題:
? ? ? ?誰的薪資比叢浩高???
?select?*?from?emp?where?sal?>(select?sal?from?emp?where?ename='從浩');
定義:子查詢允許把一個查詢嵌套在另一個查詢當(dāng)中
? ? ? ? ? ?子查詢又叫做內(nèi)部查詢,相當(dāng)于內(nèi)部查詢。包含內(nèi)部查詢的就稱為外部查詢。子查詢的結(jié)果被主查詢所使用。
注意的問題: ? ? ? ?
1.括號 ? ? ?
?2.可以在主查詢的where select having from 后面,都可以使用子查詢 ? ? ? ?
3.不可以再group by 后面使用子查詢 ? ? ? ?
4.主查詢和子查詢可以不是同一張表;只有子查詢返回的值,主查詢可以使用。
需求:查詢部門名稱是人力的員工信息
第一種方式:利用子查詢
select?*?from?emp?where?deptno=(select?deptno?from?dept?where?dname='人力部');
第二種方式:利用關(guān)聯(lián)查詢
?select?*?from?emp?e,dept?d?where?e.deptno?=?d.deptno?and?d.dname='人力部';
SQL優(yōu)化:盡量使用多表查詢
? ? ? ? ? ? ? ?絕大部分的子查詢再最終執(zhí)行的時候他都是轉(zhuǎn)換成一個多表查詢來執(zhí)行的。 ?通過SQL執(zhí)行計劃可以看出來。
? ? ? ? ? ? ? ?通過SQL執(zhí)行計劃會發(fā)現(xiàn)兩種方式執(zhí)行的是一樣的。
5.from后面的子查詢
? ? ? ? ? ? ? ?需求:
? ? ? ? ? ? ? ? ? ?查詢員工號 ? 姓名 ? ? ?月薪
select?empno,ename,sal?from?emp;
6.一般不在子查詢中排序 ? ? ? ?
7.一般先執(zhí)行子查詢,再去執(zhí)行主查詢
ANY關(guān)鍵字
假設(shè)any內(nèi)部的查詢返回結(jié)果個數(shù)是三個,如:result1,result2,result3,那么
select?....?from?..?where?a?>?any(...); ->select?.....?from?...?where?a?>?result1?or?a?>result2??or?a?>result3;
需求:
? ?查詢工資比1號部門中任意一個員工高的信息
select?*?from?emp?where?sal?>?any(select?sal?from?emp?where?deptno?=?1);
ALL關(guān)鍵字
ALL關(guān)鍵字與any關(guān)鍵字類似,只不過上面的or改成and :
select?....?from?..?where?a?>?all(...); ->select?.....?from?...?where?a?>?result1?and?a?>result2??and?a?>result3;
需求:
? ?查詢工資比1號部門中所有員工號的員工信息
???select?*?from?emp?where?sal?>?all(select?sal?from?emp?where?deptno?=?1);
SOME關(guān)鍵字
some 關(guān)鍵字和any關(guān)鍵字是一樣的功能。所以:
select?....?from?..?where?a?>?any(...); ->select?.....?from?...?where?a?>?result1?or?a?>result2??or?a?>result3;
IN關(guān)鍵字
IN運算符用于where表達(dá)式中,以列表向的形式支持多個選擇。語法如下:
where?column?in?(v1,v2,v3,.....);???????? where?column?not?in?(v1,v2,v3,.....);
當(dāng)in前面加上not運算符時候,表示與in相反的意思,既不在這寫列表項中選擇。
案例:
? ?查詢部門名稱是人力和研發(fā)的員工
?select?*?from?emp?where?deptno?in???(select?deptno?from?dept?where?dname='人力部'?or?dname='研發(fā)部') 分類:?MySQL數(shù)據(jù)庫
想了解更多相關(guān)問題請訪問PHP中文網(wǎng):MySQL視頻教程