1.表與表之間的關係 2.為什麼要使用多張表 3.概念 4.分類 ANY關鍵字 ALL關鍵字 SOME關鍵字 IN關鍵字 ...
1.表與表之間的關係
一對一:用戶表和身份信息表,用戶表是主表
例如:男人表 、女人表
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)
);
一對多:最常見的表關係,用戶表和訂單表
例如:員工表、部門表
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)
);
多對多:例如學生表和課程表,通常情況都是將多對多的關係拆分為一對多或者多對一的關係。
至少需要三張表
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 ('數學');
insert into course (cname) values ('英語');
insert into course (cname) values ('化學');
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.為什麼要使用多張表
避免出現大量的數據的冗餘。
並不是表拆的越多就越好,根據實際情況進行拆分。
3.概念
同時查詢多張表
4.分類
<1>合併查詢
union ,union all
合併結果集,就是把兩個select語句的查詢結果合併到一起。(相當於並集)
合併的兩個結果,列數和列的順序,類需要一致
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;
<2>連接查詢
員工表
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) #部門地址
);
內連接: 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 右表所有的行,如果左表中某行在右表沒有匹配,則結果中對應的左表的部門全部為空(null)
select * from emp e right OUTER JOIN dept d ON e.deptno = d.deptno;
自連接:
自連接就是說,在同一個數據表中,看作是兩個表,表示查找每個人的領導,如果沒有領導,則顯示無領導
把一張表看作成兩張表,一張員工表,一張領導表,都是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)
自然連接會自動判斷,以兩個表中相同的欄位為連接條件,返回查詢結果。
select * from emp natural join dept;
select * from emp NATURAL left join dept;
select * from emp NATURAL right join dept;
註意:內連接不寫連接條件會出現笛卡爾積的結果,應該避免這種情況,而外連接不寫連接條件會報錯。
<3>子查詢(ANY子查詢、IN子查詢、SOME子查詢、ALL子查詢)
子查詢解決的問題:
誰的薪資比叢浩高???
select * from emp where sal >(select sal from emp where ename='從浩');
定義:子查詢允許把一個查詢嵌套在另一個查詢當中
子查詢又叫做內部查詢,相當於內部查詢。包含內部查詢的就稱為外部查詢。子查詢的結果被主查詢所使用。
註意的問題:
1.括弧
2.可以在主查詢的where select having from 後面,都可以使用子查詢
3.不可以再group by 後面使用子查詢
4.主查詢和子查詢可以不是同一張表;只有子查詢返回的值,主查詢可以使用。
需求:查詢部門名稱是人力的員工信息
第一種方式:利用子查詢
select * from emp where deptno=(select deptno from dept where dname='人力部');
第二種方式:利用關聯查詢
select * from emp e,dept d where e.deptno = d.deptno and d.dname='人力部';
SQL優化:儘量使用多表查詢
絕大部分的子查詢再最終執行的時候他都是轉換成一個多表查詢來執行的。 通過SQL執行計劃可以看出來。
通過SQL執行計劃會發現兩種方式執行的是一樣的。
5.from後面的子查詢
需求:
查詢員工號 姓名 月薪
select empno,ename,sal from emp;
6.一般不在子查詢中排序
7.一般先執行子查詢,再去執行主查詢
ANY關鍵字
假設any內部的查詢返回結果個數是三個,如: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關鍵字
ALL關鍵字與any關鍵字類似,只不過上面的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關鍵字
some 關鍵字和any關鍵字是一樣的功能。所以:
select .... from .. where a > any(...);
->
select ..... from ... where a > result1 or a >result2 or a >result3;
IN關鍵字
IN運算符用於where表達式中,以列表向的形式支持多個選擇。語法如下:
where column in (v1,v2,v3,.....);
where column not in (v1,v2,v3,.....);
當in前面加上not運算符時候,表示與in相反的意思,既不在這寫列表項中選擇。
案例:
查詢部門名稱是人力和研發的員工
select * from emp where deptno in (select deptno from dept where dname='人力部' or dname='研發部')