2019-03-24 SQL常用語句(二)

1.數(shù)據(jù)完整性

在查詢的時(shí)候可以沒有外鍵約束,就算沒有外鍵約束也可以進(jìn)行查詢,但是在添加,更新的時(shí)候必須要有。

保證用戶輸入的數(shù)據(jù)保存到數(shù)據(jù)庫當(dāng)中是正確的(保存到數(shù)據(jù)庫當(dāng)中的數(shù)據(jù)是正確的)。具體做法是在建表的時(shí)候給約束,完整性可以分為一下三類

實(shí)體完整性
域完整性
引用完整性

(一)實(shí)體完整性

表當(dāng)中的一行就代表一個(gè)實(shí)體,實(shí)體完整性的作用是約束每一行的數(shù)據(jù)不能重復(fù),完整性約束主要可以分為一下三類

主鍵約束(primary key)
唯一約束(unique)
自動(dòng)增長列(auto_increment)
1.主鍵約束

特點(diǎn):每個(gè)表當(dāng)中要有一個(gè)主鍵,并且數(shù)據(jù)唯一,不能為null
添加方式:

**********************建表的同時(shí)創(chuàng)建主鍵*****************
create table 表名(字段1 數(shù)據(jù)類型  primary key,字段2 數(shù)據(jù)類型.....字段n 數(shù)據(jù)類型);
create table 表名(字段1 數(shù)據(jù)類型,字段2 數(shù)據(jù)類型....primary key(要設(shè)置主鍵的字段));
create table 表名(字段1 數(shù)據(jù)類型,字段2 數(shù)據(jù)類型....primary key(主鍵1,主鍵2...));
*********************先建表,在創(chuàng)建主鍵******************************** 
1.建表
2.修改表,添加主鍵
alter table 表名 add constraint primary key (id);
image.png
create table person(
    id bigint primary key,
    name varchar(10)
);
**********************************************
create table person(
    id bigint,
    name varchar(10),
    age int,
    primary key (id)
);
******************************************************
-- 聯(lián)合主鍵,兩個(gè)主鍵合起來作為一個(gè)聯(lián)合主鍵,
-- 兩個(gè)主鍵都不能為null,不能有2個(gè)重復(fù),可以有1個(gè)重復(fù)
create table student(
    id bigint,
    snum bigint,
    sname varchar(10),
    primary key(id,snum)
);

*********************************************
alter table students add constraint primary key(id);
2.唯一性約束
image.png

特點(diǎn):指定列的數(shù)據(jù)不能重復(fù),可以為null(可以有多個(gè))
格式:

create table 表名(字段1 數(shù)據(jù)類型 unique,字段二 數(shù)據(jù)類型......);

注意主鍵約束可以有多個(gè)null

create table student(
    id bigint primary key,
    name varchar(50) unique,
    age int
); 
3.字段增長列
image.png

特點(diǎn):指定列的數(shù)據(jù)自動(dòng)增長,即使數(shù)據(jù)刪除了,還是村刪除的序號(hào)往下繼續(xù)增長。
格式:

create table 表名(字段1 數(shù)據(jù)類型 primary key auto_increment,字段2 數(shù)據(jù)類型....);
create table student(
    id bigint primary key auto_increment,
    name varchar(20) unique,
    age int
);

(二)域完整性

使用:限制此單元格的數(shù)據(jù)正確,不與此列的其他單元格進(jìn)行比較,域代表當(dāng)前當(dāng)單元格。
域完整性約束主要分為一下三個(gè)方面:

數(shù)據(jù)類型:數(shù)值類型,日期類型,字符串類型
非空約束(not null)
默認(rèn)值約束(default)
1.非空約束,默認(rèn)值約束
create table 表名(字段1 數(shù)據(jù)類型 not null,字段2 數(shù)據(jù)類型....);
create table 表名(字段1 數(shù)據(jù)類型 default '男',字段2 數(shù)據(jù)類型....);
create table student(
    id bigint primary key auto_increment,
    name varchar(50) unique not null,
    gender char(2) default '男'
);

(三)參照完整性

什么是參照完整性:是指表于表之間的一種對(duì)應(yīng)關(guān)系,通常情況下可以通過設(shè)置2張表之間的主鍵,外鍵關(guān)系,或者編寫2張表的觸發(fā)器來實(shí)現(xiàn),有對(duì)應(yīng)參照完整性的2張表,對(duì)他們的數(shù)據(jù)進(jìn)行插入刪除更新操作的時(shí)候,系統(tǒng)都會(huì)將被修改表格與另一張對(duì)應(yīng)的表格進(jìn)行對(duì)照,從而阻止一些不正確的數(shù)據(jù)的操作。

數(shù)據(jù)庫的主鍵和外鍵類型必須要一致
2個(gè)表必須要是Innodb類型
設(shè)置參照完整性后,外鍵當(dāng)中的內(nèi)值,必須是主鍵當(dāng)中的內(nèi)容
一個(gè)表設(shè)置當(dāng)中的字段為主鍵,設(shè)置主鍵的為主表
創(chuàng)建表時(shí),設(shè)置外鍵,設(shè)置外鍵的為子表
create table  stu(
    id int primary key,
    name varchar(50),
    age int
);
-- 設(shè)置score當(dāng)中的sid為外鍵,和stu當(dāng)中的主鍵id關(guān)聯(lián)
create table score(
    sid int,
    score  int,
    constraint sc_st_fk foreign key (sid) references stu(id)
);
***************如果表以及建好了,可以使用SQL語句添加外鍵***********
alter table score add constraint foreign key (sid) references stu(id);

2.多表關(guān)系的創(chuàng)建

創(chuàng)建多對(duì)多關(guān)系的方法:創(chuàng)建一個(gè)中間關(guān)系表來實(shí)現(xiàn)

image.png

-- 多對(duì)多,要?jiǎng)?chuàng)建中間表
create table teacher(
    tid int primary key ,
    name varchar(50)
);
create table student(
    sid int primary key,
    name varchar(50)
);
-- 注意此處的字段名不能亂寫,必須要是前兩個(gè)表的主鍵,不然是無用的
create table tea_stu_rel(
    tid int,
    sid int
);
-- 添加中間表與其他表的聯(lián)系(設(shè)置外鍵),中間表當(dāng)中的字段都要設(shè)置外鍵.
alter table tea_stu_rel add constraint foreign key (tid) references teacher(tid);
alter table tea_stu_rel add constraint foreign key (sid) references student(sid);
總結(jié):中間表約束創(chuàng)建完成之后,添加到中間表當(dāng)中的數(shù)據(jù)全部是表一表二當(dāng)中的數(shù)據(jù),加入其他的數(shù)據(jù)會(huì)報(bào)錯(cuò)。

3.外什么要拆分表?

為了避免大量冗余數(shù)據(jù)的出現(xiàn)

image.png

4.多表查詢

多表查詢大致分為以下四個(gè)方面:

合并結(jié)果集
連接查詢
子查詢
自連接

(一)合并結(jié)果集

image.png
-- 合并結(jié)果集
create table A(
    name varchar(50),
    score int
);
create table B(
    name varchar(20),
    score int
);
insert into A values('a',80),('b',90);
insert into B values('a',80),('c',90),('b',100),('d',120)
select * from A union select * from B;
select * from A union all select * from B;
******************************************************
注意:在合并結(jié)果集的時(shí)候,要求2張表的列和列數(shù)據(jù)類型一致,不然不能合并

(二)連接查詢

image.png
*********************多表查詢會(huì)出現(xiàn)笛卡爾積結(jié)果集***********************
select * from student,teacher
笛卡爾積的記錄書:A記錄數(shù)*B記錄數(shù)
1.如何保證數(shù)據(jù)的正確性,避免笛卡爾積結(jié)果集?
image.png
select * from stu,score where stu.id=score.sid;
***************************************************
在查詢時(shí)保持主鍵和外鍵的一致性
主表當(dāng)中的數(shù)據(jù)參照子表當(dāng)中的數(shù)據(jù)
原理:逐行判斷,相等的留下,不相等的全部要。
2.連接查詢分類
注意查詢的時(shí)候可以沒有主外鍵約束

連接查詢主要可以分為以下三類:

內(nèi)連接
外連接
自然連接
(一)內(nèi)連接

內(nèi)連接可以分為如下的三種:

等值連接
多表連接
非等值連接
1.等值連接
**********************內(nèi)連接*********************************
-- 注意查詢的時(shí)候雖然沒有主外鍵約束,但是我們?cè)谛睦锩鎽?yīng)該明白有主外鍵約束
-- 99寫法
select * from stu st,score sc where st.id=sc.id;
select * from stu st inner join score sc on st.id=sc.id;
select * from  stu st join score sc on st.id=sc.id;
*******************************************************
select * from stu st join score sc on st.id=sc.id where score>80;
2.多表連接

image.png

表如下:


image.png
-- 查詢處學(xué)生的姓名,分?jǐn)?shù),科目,在此處是三表查詢
select st.name,sc.score ,cs.name from stu st,score sc ,course cs
where st.id=sc.id and sc.sid=cs.cid;
*******************************************************************
select st.name,cs.name,sc.score from stu st 
    inner join score sc on st.id=sc.id
    inner join course cs on sc.sid=cs.cid;
查詢結(jié)果
總結(jié):在進(jìn)行多表查詢的時(shí)候,具體的做法是一步一步,兩表進(jìn)行查詢。
3.非等值連接

非等值查詢:即查詢后面的條件不是等值的

image.png

-- 查詢所有員工的姓名,工資,所在部門名稱以及該工資的等級(jí)
select emp.ename,emp.salary ,dept.dname ,salgrade.grade from 
    emp,dept ,salgrade
    where emp.deptno=dept.deptno
    and emp.salary>=salgrade.lowSalary 
    and emp.salary<=salgrade.higghSalary;
***************************************************
select e.ename,e.salary,d.dname,s.grade from emp e 
    inner join dept d on e.deptno=d.deptno
    inner join salgrade s on  e.salary between s.lowSalary and s.higghsalary;
(二)外連接

外連接可以分為:

左外連接(左連接)
右外連接(右連接)
1.左連接

將2表滿足條件的數(shù)據(jù)查詢出來,如果左邊表右不同的數(shù)據(jù),被左邊表當(dāng)中的數(shù)據(jù)查詢出來

select * from stu st left  outer join score sc on st.id=sc.id;
2.右鏈接
image.png
select * from stu st right  outer join score sc on st.id=sc.id;
(三)自然連接
image.png
-- 不加where條件的時(shí)候,求出的結(jié)果是笛卡爾積的結(jié)果
select * from stu,score;
select * from stu ,score where stu.id=score.id;
select * from stu inner join score on stu.id=score.id;

-- 自然連接,當(dāng)有相同列名及數(shù)據(jù)類型的時(shí)候,會(huì)按照主外鍵查
-- 如果沒有對(duì)應(yīng)的,會(huì)進(jìn)行笛卡爾積查詢
select * from stu natural join score;

總結(jié):


表之間連接關(guān)系

4.子查詢

什么是子查詢:一個(gè)select語句當(dāng)中包含另一個(gè)select語句,或者多個(gè)select語句。
子查詢出現(xiàn)的位置:

where后:把select查詢出來的結(jié)果當(dāng)成另一個(gè)select的條件值。
from后:把查詢出來的結(jié)果當(dāng)成一個(gè)新表。

(一)where后

查詢出和項(xiàng)羽同部門的員工名稱

-- 查詢與項(xiàng)羽同一部門的員工
-- 先查詢項(xiàng)羽所在的部門,再查詢同部門人員
select emp.deptno from emp where emp.ename='項(xiàng)羽' ;
select ename ,empno from emp 
    where deptno=(select emp.deptno from emp where emp.ename='項(xiàng)羽');

(二)from后

查詢30號(hào)部門里面所有員工的薪資

-- 查詢30號(hào)部門所有薪資大于2000的員工
-- 先查詢30號(hào)部門的員工的工資,再查詢大于2000的
select ename,salary from emp where deptno=30;
select es.ename ,es.salary from (select ename,salary from emp where deptno=30) es
where es.salary>2000;

(三)練習(xí)

-- 查詢薪資高于程咬金的員工
第一步查詢出程咬金的薪水,第二部查詢出薪水大于他的員工
select e.salary from  emp e where e.ename='程咬金';
select * from emp 
    where emp.salary>(select e.salary from  emp e where e.ename='程咬金');
*****************************************************************
-- 查詢工資高于30號(hào)部門所有人的員工信息
-- 第一步查詢出30號(hào)部門的最高工資,第二部查處大于最高工資的所有人信息
select max(salary) from emp where deptno=30;
select * from emp 
    where emp.salary>(select max(salary) from emp where deptno=30);
******************************************************************************
-- 查詢工作和工資都與妲己完全相同的員工的信息
-- 第一步查詢妲己的工作和工資,第二部查詢相同的員工
select salary,job from emp where ename='妲己';
select * from emp
    where job=(select job from emp where ename='妲己')
    and salary=(select salary from emp where ename='妲己');
select * from emp 
    where (salary,job) in (select salary,job from emp where ename='妲己');
-- 利用99查詢查詢出共同的數(shù)據(jù)(salary,job相同)
select * from emp,(select salary,job from emp where ename='妲己') sj
    where emp.salary=sj.salary
    and emp.job=sj.job;
******************************************************************************
-- 查詢有2個(gè)以上直接下屬的員工信息
-- 對(duì)上級(jí)字段mgr進(jìn)行統(tǒng)計(jì),有2個(gè)相同說明,該編號(hào)所對(duì)應(yīng)的人有2個(gè)直接下級(jí)
select mgr,group_concat(mgr),count(mgr) from emp group by mgr having count(mgr)>2;
select * from emp 
    where empno in (select mgr from emp group by mgr having count(mgr)>2);
*************************************************************************
-- 查詢編號(hào)為7788的員工的名稱,員工工資,部門名稱,部門地址
select e.ename,e.salary ,d.dname ,d.local from emp e ,dept d 
    where e.deptno=d.deptno 
    and e.empno=7788;
***********************切記不可寫成以下的形式*****************************
select e.ename,e.salary ,d.dname ,d.local from emp e ,dept d 
    where e.empno=7788;
總結(jié):這是錯(cuò)誤的,因?yàn)樵谶M(jìn)行多表查詢的時(shí)候,沒有寫連接字段,肯定是錯(cuò)誤的。

5.自連接

自己連接自己,起別名

-- 求7902的員工編號(hào),姓名,經(jīng)理編號(hào),經(jīng)理姓名
select mgr from emp where empno=7369;
select ename from emp where empno=(select mgr from emp where empno=7369);

select e1.ename,e1.empno,e2.mgr,e2.ename from emp e1,emp e2
    where e1.empno=e2.mgr
    and e1.empno=7902;
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • SQL語言基礎(chǔ) 本章,我們將會(huì)重點(diǎn)探討SQL語言基礎(chǔ),學(xué)習(xí)用SQL進(jìn)行數(shù)據(jù)庫的基本數(shù)據(jù)查詢操作。另外請(qǐng)注意本章的S...
    厲鉚兄閱讀 5,347評(píng)論 2 46
  • MYSQL 基礎(chǔ)知識(shí) 1 MySQL數(shù)據(jù)庫概要 2 簡(jiǎn)單MySQL環(huán)境 3 數(shù)據(jù)的存儲(chǔ)和獲取 4 MySQL基本操...
    Kingtester閱讀 7,857評(píng)論 5 116
  • 注:1.mysql是一種關(guān)系型數(shù)據(jù)庫 2.大小寫不敏感 3.字符串用單引號(hào),若字符串里有單引號(hào),則...
    孫浩j閱讀 1,341評(píng)論 0 2
  • 問題1:char、varchar的區(qū)別是什么?varchar是變長而char的長度是固定的。如果你的內(nèi)容是固定大小...
    風(fēng)的低語閱讀 1,206評(píng)論 0 8
  • 四哥發(fā)了一個(gè)微信“好男人裝聾作啞,任女人嘮叨不休“,我看了一下,沒有回復(fù),估計(jì)是跟四嫂又杠上了,沒落到好果子吃。 ...
    米陌陌閱讀 331評(píng)論 0 0