MySQL字段約束及多表查詢---講解三

前言:mysql的字段約束是之後必不可免的,下面主要寫了四個:主鍵約束用於惟一且不能爲空;非空約束即不能爲空能夠重複;惟一約束便可覺得空但必須惟一;外鍵約束是讓表與表之間有必定的關聯;固然如何使用還看下文,多表就不在這總結了。若是你對前面的知識有所遺忘或感興趣----MySQL數據庫表的模糊/多行/分組/排序/分頁查詢以及字mysql數據類型的講解---講解二mysql


7 mysql的字段約束

7.1 主鍵約束

主鍵約束:若是爲一個列添加了主鍵約束,那麼這個列就是主鍵,主鍵的特色是惟一且不能爲空。
主鍵的做用是: 惟一的標識一條表記錄(就像身份證號用於惟一的表示一我的同樣)
添加主鍵約束,例如將id設置爲主鍵:
(一般一張表中會有一個主鍵)sql

create table stu(
    id int primary key auto_increment,
   
);

關於主鍵自增:數據庫

(1)設置了主鍵自增後, 再往表中插入記錄,就能夠不用給主鍵賦值,直接插入一個null值便可
(2)設置了主鍵自增後, 也能夠爲id賦值,只要賦的值與已有的id值不衝突便可! 在底層會將 auto_increment變量的值和插入的id值進行比較, 若是插入的值較大, 將會將插入的值加1後賦值給auto_increment變量函數

7.2 非空約束

非空約束:若是爲一個列添加了非空約束,那麼這個列的值就不能爲空,但能夠重複。
添加非空約束,例如爲password添加非空約束:.net

create table user(
    password varchar(50) not null,
    ...
);

7.3 惟一約束

惟一約束:若是爲一個列添加了惟一約束,那麼這個列的值就必須是惟一的(即不能重複),但能夠爲空。
添加惟一約束,例如爲username添加惟一約束及非空約束:設計

create table user(
    username varchar(50) unique not null,
    ...
);

7.4 外鍵約束

設置外鍵和不設置外鍵有什麼區別? 若是不設置外鍵,兩張表之間的對應關係就只有開發人員本身知道,數據庫自己是不知道的,數據庫不知道兩張表存在對應關係,就不會幫咱們維護這段關係。只有開發人員本身來維護。code

若是設置了外鍵,就等同於通知數據庫兩張表(dept和emp)存在必定的對應關係(emp表中的dept_id列要嚴格參考dept表中的主鍵(id)),數據庫知道而且會幫咱們維護這段關係。blog

create table dept(
    id int,
    name varchar(50)
    ...
);

create table emp(
    id int,
    name varchar(50),
    dept_id int,
    foreign key(dept_id) references dept(id)
);

8 表關係

常見的表關係有: 一對多(多對一)、一對1、多對多
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述排序

總結:圖片

一對多(多對一):在多的一方添加列(員工和部門)保存一的一方的主鍵做爲外鍵,從而保存兩張表之間的對應關係

一對一:在任意一張表中添加列保存另外一方的主鍵做爲外鍵,從而保存兩張表之間的對應關係

多對多:不能在任意一方添加列保存另外一方的主鍵。此時能夠建立一張第三方的表,分別保存兩張表的主鍵做爲外鍵,從而保存多對多的對應關係。

多表查詢

將db30庫中的數據導入數據庫

-- -----------------------------------
-- 建立db30庫、dept表、emp表並插入記錄
-- -----------------------------------

-- 刪除db30庫(若是存在)
drop database if exists db30;
-- 從新建立db30庫
create database db30 charset utf8;
-- 選擇db30庫
use db30;

-- 刪除部門表, 若是存在
drop table if exists dept;
-- 從新建立部門表, 要求id, name字段
create table dept(
	id int primary key auto_increment,	-- 部門編號
	name varchar(20)					-- 部門名稱
);
-- 往部門表中插入記錄
insert into dept values(null, '財務部');
insert into dept values(null, '人事部');
insert into dept values(null, '科技部');
insert into dept values(null, '銷售部');

-- 刪除員工表, 若是存在
drop table if exists emp;
-- 建立員工表(員工編號、員工姓名、所在部門編號)
create table emp(
	id int primary key auto_increment,	-- 員工編號
	name varchar(20),					-- 員工姓名
	dept_id int							-- 部門編號
);
-- 往員工表中插入記錄
insert into emp values(null, '張三', 1);
insert into emp values(null, '李四', 2);
insert into emp values(null, '老王', 3);
insert into emp values(null, '趙六', 5);

9.1 鏈接查詢

--42.查詢部門和部門對應的員工信息

select * from dept, emp;
上面的查詢叫作笛卡爾積查詢:若是同時查詢兩張表,其中一張表有m條數據,另一張表有n條數據,笛卡爾積查詢的結果是 m*n 條
笛卡爾積查詢的結果中有大量錯誤數據,咱們一般不會直接使用。
但能夠經過where子句、條件剔除錯誤數據,保留正確數據。
正確代碼:

select * from dept, emp where dept.id=emp.dept_id;

9.2左外鏈接查詢

-- 43.查詢全部部門和部門下的員工,若是部門下沒有員工,員工顯示爲null
select * from dept left join emp on dept.id=emp.dept_id;

在這裏插入圖片描述

左外鏈接查詢:會將左邊表中的全部記錄都查詢出來,右邊表只顯示和左邊表對應的數據,若是左邊表在右邊沒有對應數據,能夠對應null值。

-- 也可使用右外鏈接實現上面的查詢
select * from emp right join dept on emp.dept_id=dept.id;

9.3右外鏈接查詢

-- 44.查詢部門和全部員工,若是員工沒有所屬部門,部門顯示爲null
select * from dept right join emp on dept.id=emp.dept_id;

在這裏插入圖片描述

右外鏈接查詢:會將右邊表中的全部記錄都查詢出來,左邊表只顯示和右邊表對應的數據,若是右邊表在左邊沒有對應數據,能夠對應null值。

-- 也可使用左外鏈接實現上面的查詢:
select * from emp left join dept on dept.id=emp.dept_id;

-- 查詢全部的部門和對應的全部員工(既要顯示全部部門,也要顯示全部員工)
select * from emp full join dept on dept.id=emp.dept_id;

mysql不支持全外鏈接查詢,但咱們能夠經過union(聯合)查詢來模擬:
select * from dept left join emp on dept.id=emp.dept_id
union
select * from dept right join emp on dept.id=emp.dept_id;

9.4子查詢

子查詢:將一條SQL語句的執行結果,做爲另一條SQL語句的條件進行查詢,這樣的查詢就叫作子查詢。
將對db40庫導入數據庫中

-- -----------------------------------
-- 建立db40庫、dept表、emp表並插入記錄
-- -----------------------------------

-- 刪除db40庫(若是存在)
drop database if exists db40;
-- 從新建立db40庫
create database db40 charset utf8;
-- 選擇db40庫
use db40;

-- 建立部門表
create table dept(				-- 建立部門表
	id int primary key,			-- 部門編號
	name varchar(50),			-- 部門名稱
	loc varchar(50)				-- 部門位置
);

-- 建立員工表
create table emp(				-- 建立員工表
	id int primary key,			-- 員工編號
	name varchar(50),			-- 員工姓名
	job varchar(50),			-- 職位
	topid int,					-- 直屬上級
	hdate date,					-- 受僱日期
	sal int,					-- 薪資
	bonus int,					-- 獎金
	dept_id int,				-- 所在部門編號
	foreign key(dept_id) references dept(id)
);

-- 往部門表中插入記錄
insert into dept values ('10', '財務部', '北京');
insert into dept values ('20', '設計部', '上海');
insert into dept values ('30', '技術部', '廣州');
insert into dept values ('40', '銷售部', '深圳');

-- 往員工表中插入記錄
insert into emp values ('1001', '王富國', '辦事員', '1007', '1980-12-17', '800', 500, '20');
insert into emp values ('1003', '齊帥', '分析員', '1011', '1981-02-20', '1900', '300', '10');
insert into emp values ('1005', '王浪', '推銷員', '1011', '1981-02-22', '2450', '600', '10');
insert into emp values ('1007', '馮鬆', '經理', '1017', '1981-04-02', '3675', 700, '20');
insert into emp values ('1009', '李政', '推銷員', '1011', '1981-09-28', '1250', '1400', '10');
insert into emp values ('1011', '陳要', '經理', '1017', '1981-05-01', '3450', 400, '10');
insert into emp values ('1013', '張勇', '辦事員', '1011', '1981-06-09', '1250', 800, '10');
insert into emp values ('1015', '程德祖', '分析員', '1007', '1987-04-19', '3000', 1000, '20');
insert into emp values ('1017', '韓悅', '董事長', null, '1981-11-17', '5000', null, null);
insert into emp values ('1019', '劉笑', '推銷員', '1011', '1981-09-08', '1500', 500, '10');
insert into emp values ('1021', '范冰冰', '辦事員', '1007', '1987-05-23', '1100', 1000, '20');
insert into emp values ('1023', '趙子龍', '經理', '1017', '1981-12-03', '950', null, '30');
insert into emp values ('1025', '雪雅', '分析員', '1023', '1981-12-03', '3000', 600, '30');
insert into emp values ('1027', '張大膽', '辦事員', '1023', '1982-01-23', '1300', 400, '30');

-- 45.列出薪資比'劉笑'薪資高的全部員工,顯示姓名、薪資

-- 查詢'劉笑'的薪資
select sal from emp where name='劉笑';

-- 查詢薪資比'劉笑'薪資高的全部員工
select name, sal from emp
where sal > (select sal from emp where name='劉笑');

-- 46.列出與'雪雅'從事相同職位的全部員工,顯示姓名、職位。

-- 求出雪雅的職位
select job from emp where name='雪雅';

-- 求與'雪雅'從事相同職位的員工
select name, job from emp
where job=(select job from emp where name='雪雅');

-- 47.列出薪資比'技術部'部門(已知部門編號爲30)全部員工薪資都高的員工信息,顯示員工姓名、薪資和部門名稱。

-- 求技術部門的最高薪資
select max(sal) from emp where dept_id=30;

-- 鏈接查詢員工表和部門表
select emp.name,sal,dept.name from emp, dept
where emp.dept_id=dept.id
and sal>(select max(sal) from emp where dept_id=30); -- 不許確
---------------------------------------------------------
select emp.name,sal,dept.name from emp left join dept
on emp.dept_id=dept.id
where sal>(select max(sal) from emp where dept_id=30);

9.5 多表查詢

-- 48.列出在'設計部'任職的員工,假定不知道'設計部'的部門編號, 顯示部門名稱,員工名稱

-- 關聯查詢兩張表
select dept.name, emp.name from emp,dept
where dept.id=emp.dept_id;

-- 求出在培優部的員工
select dept.name, emp.name from emp,dept
where dept.id=emp.dept_id and dept.name='設計部';

-- 49.(自查詢)列出全部員工及其直接上級,顯示員工姓名、上級編號,上級姓名

/* 將emp表既看做員工表, 也看作上級表 e1(員工表) e2(上級表)
 查詢的列: e1.name, e2.id, e2.name
 查詢的表: emp e1,emp e2
 鏈接條件: e1.topid=e2.id
*/

select e1.name, e2.id, e2.name
from emp e1,emp e2
where e1.topid=e2.id;
 
select e1.name, e2.id, e2.name
from emp e1 left join emp e2
on e1.topid=e2.id; -- 左外,查詢全部員工及對應上級

-- 50.列出最低薪資大於1500的各類職位,顯示職位和該職位最低薪資

-- 求出每種職位的最低薪資分別是多少
select job,min(sal) from emp group by job;

-- 求出最低薪資大於1500的職位
select job,min(sal) from emp group by job having min(sal)>1500;
-- 在分組以前過濾使用where,在分組以後過濾使用having

-- 51.列出在每一個部門就任的員工數量、平均工資。顯示部門編號、員工數量,平均薪資。

-- 對員工表按照部門分組(部門相同的員工爲一組)
select dept_id 部門編號, count(*) 部門人數, avg(sal) 平均薪資
from emp group by dept_id;

-- 52.查出至少有一個員工的部門,顯示部門編號、部門名稱、部門位置、部門人數。

-- 鏈接查詢部門表和員工表
select d.id, d.name, d.loc from dept d, emp e
where emp.dept_id=dept.id;

-- 按照部門進行分組,統計每一個部門的人數
select d.id, d.name, d.loc, count(*)
from dept d, emp e
where e.dept_id=d.id
group by d.name;

-- 53.列出受僱日期早於直接上級的全部員工的編號、姓名、部門名稱。

/*
查詢的列:e1.id, e1.name, d.name
查詢的表:emp e1(員工表),dept d(部門表) emp e2(上級表)
鏈接條件:e1.dept_id=d.id, e1.topid=e2.id
篩選條件:e1.hdate<e2.hdate
 */

select e1.id, e1.name, d.name
from emp e1,dept d,emp e2
where e1.dept_id=d.id and e1.topid=e2.id
and e1.hdate<e2.hdate;

-- 54.列出每一個部門薪資最高的員工信息,顯示部門編號、最高薪資、員工姓名

-- 求出每一個部門的最高薪資,顯示部門編號和最高薪資
select dept_id,max(sal) from emp group by dept_id;

-- 將上面的查詢結果做爲一張表 和 emp 表進行鏈接查詢
select  e.dept_id dept_id, t.max_sal sal, e.name name
from emp e, (select dept_id,max(sal) max_sal from emp group by dept_id) t
where e.sal=t.max_sal and e.dept_id=t.dept_id;

-- 查詢沒有部門的員工的最高信息,顯示部門編號,最高薪資,員工姓名
select dept_id,sal,name from emp where
sal=(select max(sal) from emp where dept_id is null)
and dept_id is null;

select  e.dept_id dept_id, t.max_sal sal, e.name name
from emp e, (select dept_id,max(sal) max_sal from emp group by dept_id) t
where e.sal=t.max_sal and e.dept_id=t.dept_id
union
select dept_id,sal,name from emp where
sal=(select max(sal) from emp where dept_id is null)
and dept_id is null;

在sql語句中where和having的區別

相同點:where和having都用於對錶中的記錄進行篩選過濾

不一樣點
(1)where是在分組以前,對錶中的記錄進行篩選過濾。而且where中不能使用列別名(但可使用表別名),也不能使用多行函數(count/max/min/sum/avg)
(2)having是在分組以後,對錶中的記錄進行篩選過濾,having中可使用列別名、表別名、多行函數。
(3)一般狀況,having能夠替代where,但反過來不行(但有些狀況下不能替換:在分組以前須要對記錄進行過濾,分組以後還須要對數據進行過濾,此時不能使用having替換where)


到此對數據庫的詳細講解也經過三篇博文,講解清楚了,若是有問題,能夠在評論區找我!!!

相關文章
相關標籤/搜索