create table DEPT
(
DEPTNO int(2) not null,
DNAME varchar(14),
LOC varchar(13)
)
;
alter table DEPT
add constraint PK_DEPT primary key (DEPTNO);
create table EMP
(
EMPNO int(4) not null,
ENAME varchar(10),
JOB varchar(9),
MGR int(4),
HIREDATE date,
SAL int(7 ),
COMM int(7 ),
DEPTNO int(2)
)
;
alter table EMP
add constraint PK_EMP primary key (EMPNO);
alter table EMP
add constraint FK_DEPTNO foreign key (DEPTNO)
references DEPT (DEPTNO);
insert into DEPT (DEPTNO, DNAME, LOC)
values (10, 'ACCOUNTING', 'NEW YORK');
insert into DEPT (DEPTNO, DNAME, LOC)
values (20, 'RESEARCH', 'DALLAS');
insert into DEPT (DEPTNO, DNAME, LOC)
values (30, 'SALES', 'CHICAGO');
insert into DEPT (DEPTNO, DNAME, LOC)
values (40, 'OPERATIONS', 'BOSTON');
commit;
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7369, 'SMITH', 'CLERK', 7902, str_to_date('17-12-1980', '%d-%m-%Y'), 800, null, 20);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7499, 'ALLEN', 'SALESMAN', 7698, str_to_date('20-02-1981', '%d-%m-%Y'), 1600, 300, 30);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7521, 'WARD', 'SALESMAN', 7698, str_to_date('22-02-1981', '%d-%m-%Y'), 1250, 500, 30);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7566, 'JONES', 'MANAGER', 7839, str_to_date('02-04-1981', '%d-%m-%Y'), 2975, null, 20);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7654, 'MARTIN', 'SALESMAN', 7698, str_to_date('28-09-1981', '%d-%m-%Y'), 1250, 1400, 30);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7698, 'BLAKE', 'MANAGER', 7839, str_to_date('01-05-1981', '%d-%m-%Y'), 2850, null, 30);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7782, 'CLARK', 'MANAGER', 7839, str_to_date('09-06-1981', '%d-%m-%Y'), 2450, null, 10);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7788, 'SCOTT', 'ANALYST', 7566, str_to_date('19-04-1987', '%d-%m-%Y'), 3000, null, 20);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7839, 'KING', 'PRESIDENT', null, str_to_date('17-11-1981', '%d-%m-%Y'), 5000, null, 10);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7844, 'TURNER', 'SALESMAN', 7698, str_to_date('08-09-1981', '%d-%m-%Y'), 1500, 0, 30);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7876, 'ADAMS', 'CLERK', 7788, str_to_date('23-05-1987', '%d-%m-%Y'), 1100, null, 20);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7900, 'JAMES', 'CLERK', 7698, str_to_date('03-12-1981', '%d-%m-%Y'), 950, null, 30);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7902, 'FORD', 'ANALYST', 7566, str_to_date('03-12-1981', '%d-%m-%Y'), 3000, null, 20);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7934, 'MILLER', 'CLERK', 7782, str_to_date('23-01-1982', '%d-%m-%Y'), 1300, null, 10);
commit;
關系數(shù)據(jù)庫
是指一些相關的表和其他數(shù)據(jù)庫對象的集合。對于關系數(shù)據(jù)庫來說,關系就是表的同義詞。 表是由行和列組成(類似二維數(shù)組的結構)
結構化查詢語言(SQL)
對數(shù)據(jù)庫操作的普通話, 不區(qū)分大小寫
結構化查詢語言(Structured Query Language)簡稱SQL, 是操作和檢索關系型數(shù)據(jù)庫的標準語言,目前應用于各種關系型數(shù)據(jù)庫。
結構化查詢語言分類
- 數(shù)據(jù)查詢語言(DQL:Data Query Language):語句主要包括SELECT,用于從表中檢索數(shù)據(jù)。
- 數(shù)據(jù)操作語言(DML:Data Manipulation Language):語句主要包括INSERT,UPDATE和DELETE,用于添加,修改和刪除表中的行數(shù)據(jù)。
- 數(shù)據(jù)定義語言(DDL:Data Definition Language):語句主要包括CREATE、DROP、ALTER,用于定義、銷毀、修改數(shù)據(jù)庫對象
- 事務處理語言(TPL:Transaction Process Language): 語句主要包括COMMIT和ROLLBACK,用于提交和回滾。
- 數(shù)據(jù)控制語言(DCL:Data Control Language):語句主要包括GRANT和REVOKE,用于進行授權和收回權限。
Dos命令
dir 列出所有文件
cls 清屏
cd C:\phpstudy_pro\Extensions\MySQL5.7.26\bin 修改文件夾
切換盤符 D:
鏈接數(shù)據(jù)庫庫命令:
mysql -hlocalhost -uroot -p
- mysql 常用命令
show databases; 顯示所有數(shù)據(jù)庫
use 數(shù)據(jù)庫名 使用該數(shù)據(jù)庫
quit; 退出數(shù)據(jù)庫
基本查詢語句
SELECT [DISTINCT]{*|column|expression [alias],...}
FROM table;
SELECT 列名 from 表名;
選擇所有列
select deptno, dname, loc from dept;
select * from dept;
- 算術運算符
可以在SELECT語句中使用算術運算符,改變輸出結果。 |運算符|描述| |---|---| |+|加| |-|減| |*|乘 | |/| 除|
讓emp表中所員工的工資 + 200, 同時顯示之前的工資和加薪之后的工資
SELECT sal , sal+200 from emp;
- 算術運算符優(yōu)先級
1、乘除優(yōu)先于加減
2、相同優(yōu)先權的表達式按照從左至右的順序依次計算
3、括弧可以提高優(yōu)先權,并使表達式的描述更為清晰
顯示員工姓名和年薪
select ename, (sal+100)*12 from emp;
練習:
員工試用期6個月,轉(zhuǎn)正后月薪上調(diào)20%,請查詢出所有員工工作第一年的年薪所得(不考慮獎金部分,年薪的試用期6個月的月薪+轉(zhuǎn)正后6個月的月薪)
select sal*6+sal*(1+0.2)*6 from emp;
- 空值NULL
任何包含空值的算術表達式運算后的結果都為空值NULL。
select ename, sal*12+comm from emp;

列別名
使用列別名的方法
- 方式1:列名 列別名(空格)
- 方式2:列名 AS 列別名(as)
以下三種情況列別名兩側需要添加雙引號 - 列別名中包含有空格
- 列別名中要求區(qū)分大小寫(ORACLE中)
- 列別名中包含有特殊字符
select ename 員工名, sal 工資 from emp;


select ename as "員工 名", sal as 工資 from emp;
知識小課堂:
nvl(列, 值) 如果列為空,那么給與相應的默認值(oracle)
ifnull(列, 值) 如果列為空,那么給與相應的默認值(oracle)
練習:員工試用期6個月,轉(zhuǎn)正后月薪上調(diào)20%,請查詢出所有員工工作第一年的所有收入,要求顯示列標題為員工姓名,工資收入,獎金收入,總收入
select ename 員工姓名, sal 工資收入, ifnull(comm, 0) 獎金, sal*6+sal*1.2*6+ifnull(comm,0) 總收入 from emp;

- 消除重復行
SELECT distinct deptno
FROM emp;

練習: 查詢員工表中一共有哪幾種崗位類型
select distinct job from emp;
顯示表結構
desc emp;

where 語句
where 語句 可以作為查詢的限定條件
格式 : 在from之后
SELECT [DISTINCT] {*| column | expression [alias], ...}
FROM table
[WHERE condition(s)];

栗子
- 數(shù)值類型
select ename, hiredate, deptno from emp where deptno=30;

- varchar
select ename, job from emp where job = 'MANAGER ';

- date
SELECT * from emp where hiredate > '1982-01-01';

- 查詢職位為SALESMAN的員工編號、職位、入職日期。
select empno,job, hiredate from emp where job="SALESMAN";
- 查詢1985年12月31日之前入職的員工姓名及入職日期。
select ename,hiredate from emp where hiredate<"1985-12-31";
- 查詢部門編號不在10部門的員工姓名、部門編號
select ename, deptno from emp where deptno <> 10;
-
特殊比較運算符
image BETWEEN..AND 使用BETWEEN .. AND.. 運算符來判斷要比較的值是否在某個范圍內(nèi)。
select * from emp where sal between 1000 and 2000;

select * from emp where mgr in (7698, 7839, 7788);

練習:
查詢?nèi)肼毴掌谠?2年至85年的員工姓名,入職日期。
select ename,hiredate from emp where hiredate between '1982-01-01' and '1985-12-31';
查詢月薪在3000到5000的員工姓名,月薪。
select ename,sal from emp where hiredate between 3000 and 5000;
查詢部門編號為10或者20的員工姓名,部門編號。
select ename,deptno from emp where deptno in(10,20);
查詢經(jīng)理編號為7902, 7566, 7788的員工姓名,經(jīng)理編號
select ename,mgr from emp where mgr in(7902,7566,7788);
模糊查詢LIKE運算符
使用LIKE運算符判斷要比較的值是否滿足部分匹配,也叫模糊查詢。模糊查詢中兩個通配符:
- % 代表零或任意更多的字符
- _ 代表一個字符
select * from emp where ename like 'M%';
select * from emp where ename like '_A%';
LIKE通配符轉(zhuǎn)義
- 您可以使用ESCAPE標識符實現(xiàn)對“%”和 “_”的查找。
- 例:查詢 JOB 以“MAN_”開頭的雇員信息
select * from emp where JOB like 'MAN@_%'escape'@';
select * from emp where JOB like 'MAN/_%'escape'/';
IS NULL 運算符
- 使用 IS NULL 運算符來判斷要比較的值是否為空值NULL
SELECT *FROM emp WHERE mgr IS NULL;

- 查詢員工姓名以W開頭的員工姓名。
select ename from emp where ename like 'W%';
- 查詢員工姓名倒數(shù)第2個字符為T的員工姓名。
select ename from emp where ename like "%T_";
- 查詢獎金為空的員工姓名,獎金
select ename , comm from emp where comm is null;
邏輯運算符

SELECT empno, ename, job, sal FROM emp WHERE sal>=1100 AND job='CLERK';
SELECT empno, ename, job, sal FROM emp WHERE sal>=1100 or job='CLERK';
SELECT * from emp where job not in('SALESMAN','CLERK');
NOT運算符還可以和BETWEEN…AND、LIKE、IS NULL一起使用
... WHERE deptno NOT IN (10, 20)
... WHERE sal NOT BETWEEN 3000 AND 5000
... WHERE ename NOT LIKE 'D%’
... WHERE mgr IS NOT NULL
-
運算符的優(yōu)先級
image
SELECT ename, job, sal FROM emp WHERE job='SALESMAN' OR job='PRESIDENT' AND sal>1500;

SELECT ename, job, sal FROM emp WHERE (job='SALESMAN' OR job='PRESIDENT') AND sal>1500;

- 查詢工資超過2000并且職位是 MANAGER或SALESMAN的員工姓名、職位、工資。
select ename,job,sal from emp where sal > 2000 and job in ('MANAGER','SALESMAN');
- 查詢部門在10或者20,并且工資在3000到5000之間的員工姓名、部門、工資。
select ename,deptno,sal from emp where deptno in (10,20) and sal between 3000 and 5000;
- 查詢?nèi)肼毴掌谠?1年,并且職位不是SALES開頭的員工姓名、入職日期、職位。
select ename,hiredate,job from emp where hiredate between '1981-01-01' and '1982-01-01' and job not like 'SALES%';
- 查詢職位為SALESMAN或MANAGER,部門編號為10或者20,姓名包含A的員工姓名、職位、部門編號。
select ename,job,deptno from emp where job in ('SALESMAN','MANAGER') and deptno in(10,20) and ename like '%A%';
排序
- 使用ORDER BY子句能對查詢結果集進行排序,語法結構如下:
SELECT [DISTINCT] { *| 列名 | 表達式 [別名][,...] }
FROM 表名
[WHERE 條件]
[ORDER BY {列名| 表達式| 列別名| 列序號} [ASC| DESC],…];
select * from emp order by hiredate;
- 可以按照列名、表達式、列別名、結果集的列序號排序
- ASC: 升序(默認值), DESC: 降序
- ORDER BY 子句必須寫在SELECT語句的最后
規(guī)則
1、數(shù)字升序排列小值在前,大值在后。即按照數(shù)字大小順序由小到大排列。
2、日期升序排列相對較早的日期在前,較晚的日期在后。
3、字符升序排列按照字母由小到大的順序排列。即由A-Z排列;中文升序按照字典順序排列。
4、空值在升序排列中排在最前面,在降序排列中排在最后。
- 按照別名進行排序
select ename, sal*12 annsal from emp order by annsal desc;
- 多列排序
select * from emp order by deptno desc, sal desc;

- 參與排序的多列都可以指定升序或者降序
- ORDER BY子句中可以寫沒在SELECT列表中出現(xiàn)的列
select ename,deptno, sal from emp order by 2 desc, 3 desc;
- 查詢部門在20或30的員工姓名,部門編號,并按照工資升序排序。
select ename, deptno,sal from emp where deptno in(20,30) order by sal;
- 查詢工資在2000-3000之間,部門不在10號的員工姓名,部門編號,工資,并按照部門升序,工資降序排序。
select ename, deptno,sal from emp where sal between 2000 and 3000 and deptno not in(10) order by deptno,sal desc;
- 查詢?nèi)肼毴掌谠?2年至83年之間,職位以SALES或者MAN開頭的員工姓名,入職日期,職位,并按照入職日期降序排序。
select ename, hiredate, job from emp where (hiredate between '1982-01-01' and '1983-12-31') and (job like 'SALES%' or job like 'MAN%') order by hiredate desc;
LIMIT 語句(Mysql)
使用select語句時,經(jīng)常要返回前幾條或者中間某幾行記錄,可以使用關鍵字limit。語法格式如下:
SELECT 字段列表
FROM 數(shù)據(jù)源
LIMIT [start,]length;
說明: 1.limit接受一個或兩個整數(shù)參數(shù)。start表示從第幾行記錄開始輸出,length表示輸出的記錄行數(shù)。 2.表中第一行記錄的start值為0(不是 1)。
select * from emp limit 5,2;
練習
- 查詢?nèi)肼毴掌谧钤绲那?名員工姓名,入職日期。
select ename,hiredate from emp order by hiredate limit 5;
- 查詢20號部門下入職日期最早的前2名員工姓名,入職日期。
select ename,hiredate from emp where deptno =20 order by hiredate limit 2;
- 按照每頁顯示5條記錄,分別查詢第1頁,第2頁,第3頁信息,要求顯示員工姓名、入職日期、部門編號。
select ename,hiredate,deptno from emp limit 0,5;
select ename,hiredate,deptno from emp limit 5,5;
select ename,hiredate,deptno from emp limit 10,5;
本章練習
查詢?nèi)肼殨r間在1982-7-9之后,并且不從事SALESMAN工作的員工姓名、入職時間、職位。
select ename,hiredate,job from emp where hiredate > '1982-07-09' and job <> 'SALESMAN';
查詢員工姓名的第三個字母是a的員工姓名。
select ename from emp where ename like '__a%';
查詢除了10、20號部門以外的員工姓名、部門編號。
select ename,deptno from emp where deptno not in (10,20);
查詢部門號為30號員工的信息,先按工資降序排序,再按姓名升序排序。
select * from emp where deptno = 30 order by sal desc,ename;
查詢沒有上級的員工(經(jīng)理號為空)的員工姓名。
select ename from emp where mgr is null;
查詢工資大于等于4500并且部門為10或者20的員工的姓名\工資、部門編號。
select ename,sal,deptno from emp where sal >= 4500 and deptno in (10,20);
多表鏈接
連接是在多個表之間通過一定的連接條件,使表之間發(fā)生關聯(lián),進而能從多個表之間獲取數(shù)據(jù)。
語法為
SELECT table1.column, table2.column
FROM table1, table2
WHERE table1.column1 = table2.column2;
笛卡爾積: 第一個表中的所有行和第二個表中的所有行都發(fā)生連接。
為了避免笛卡爾積的產(chǎn)生,通常需要在WHERE子句中包含一個有效的連接條件
接下來我們詳細學習這些連接條件:
等值連接
select * from emp,dept where emp.deptno=dept.deptno;


select empno, ename , emp.deptno, loc from emp, dept where emp.deptno=dept.deptno and loc = 'NEW YORK';
限制歧義列名
- 在用到多個表時可以使用表名作前綴來限定列;
- 通過使用表前綴可以提高性能;
select emp.empno, emp.ename , emp.deptno, dept.loc from emp, dept where emp.deptno=dept.deptno and loc = 'NEW YORK';
- 通過使用列的別名可以區(qū)分來自不同表但是名字相同的列
select e.empno as 員工編號, e.ename 姓名,d.dname 部門名稱
from emp e, dept d where e.deptno=d.deptno;

練習:
- 寫一個查詢,顯示所有員工姓名,部門編號,部門名稱。
select e.ename,e.empno,e.job from emp e,dept d where e.deptno = d.deptno;
- 寫一個查詢,顯示所有工作在CHICAGO并且獎金不為空的員工姓名,工作地點,獎金
select e.ename,d.loc,e.comm from emp e,dept d where e.deptno = d.deptno and d.loc = 'CHICAGO' and comm is not null;
- 寫一個查詢,顯示所有姓名中含有A字符的員工姓名,工作地點。
select e.ename,d.loc from emp e,dept d where e.deptno = d.deptno and e.ename like '%A%';
非等值連接

select e.e
name 員工姓名, e.sal 工資 , s.grade 工資等級 from emp e, salgrade s where e.sal between s.losal and s.hisal;
兩個表以上的鏈接

多表連接的寫法分析
- 分析要查詢的列都來自于哪些表,構成FROM子句;
分析這些表之間的關聯(lián)關系,如果表之間沒有直接關聯(lián)關系,而是通過另一個中間表關聯(lián),則也要在FROM子句中補充中間關聯(lián)表; - 接下來在WHERE子句中補充表之間的關聯(lián)關系,通常N個表,至少要有N-1個關聯(lián)關系;
- 分析是否還有其它限制條件,補充到WHERE子句的表關聯(lián)關系之后,作為限制條件;
- 根據(jù)用戶想要顯示的信息,補充SELECT子句。
- 分析是否有排序要求,如果排序要求中還涉及到其它表,則也要進行第2步補充排序字段所在的表,并且添加表之間的關聯(lián)關系;
select e.empno 編號,e.ename 姓名,e.sal 員工薪水,s.grade 工資等級,d.loc 所在城市 from emp e,salgrade s,dept d where (e.deptno=d.deptno) and (e.sal between s.losal and s.hisal) order by s.grade;

自連接
查詢每個員工的姓名和直接上級姓名
select w.ename 員工姓名, m.ename 領導姓名 from emp w, emp m where w.mgr = m.empno;

select w.ename 員工姓名 ,w.empno 員工編號,m.ename 領導姓名,m.empno 領導編號 from emp w,emp m,dept d where w.mgr = m.empno and d.deptno = w.deptno and d.loc in('NEW YORK','CHICAGO');
交叉連接
創(chuàng)建一個員工表和部門表的交叉連接。
select e.empno, e.ename, d.dname from emp e cross join dept d;
自然連接
select e.empno, e.ename, d.dname from emp e natural join dept d;
相比于等值連接,等值連接直接指明連接條件, 自然連接是自己找(兩個表字段名相同,自動添加), 自然連接無法控制用哪些字段連接
外連接
- 左外鏈接
左外連接以FROM子句中的左邊表為基表,該表所有行數(shù)據(jù)按照連接條件無論是否與右邊表能匹配上,都會被顯示出來。
查詢所有雇員姓名,部門編號,部門名稱,包括沒有部門的員工也要顯示出來
select e.ename,e.deptno, d.dname from emp e left outer join dept d on(e.deptno = d.deptno);

- 右外鏈接
查詢所有雇員姓名,部門編號,部門名稱,包括沒有員工的部門也要顯示出來
select e.ename, e.deptno, d.dname from emp e right outer join dept d on (e.deptno = d.deptno);

創(chuàng)建一個員工表和部門表的交叉連接。
select e.ename,d.dname from emp e cross join dept d;
使用自然連接,顯示入職日期在80年5月1日之后的員工姓名,部門名稱,入職日期
select e.ename,d.dname,e.hiredate from emp e natural join dept d where e.hiredate>'1980-05-01';
使用左連接,查詢每個員工的姓名,經(jīng)理姓名,沒有經(jīng)理的King也要顯示出來。
select w.ename 員工,m.ename 經(jīng)理 from emp w left outer join emp m on (w.mgr = m.empno);
使用右連接,查詢每個員工的姓名,經(jīng)理姓名,沒有經(jīng)理的King也要顯示出來。
select w.ename 員工,m.ename 經(jīng)理 from emp m right outer join emp w on (w.mgr = m.empno);
顯示員工SMITH的姓名,部門名稱,直接上級名稱
select e.ename 員工姓名, d.dname 部門名稱, h.ename 上級名稱 from emp e, emp h,dept d where e.deptno=d.deptno and e.mgr=h.empno and e.ename='SMITH';
顯示員工姓名,部門名稱,工資,工資級別,要求工資級別大于4級。
select e.ename 員工姓名, d.dname 部門名稱, e.sal 工資,s.grade 工資等級 from emp e, salgrade s,dept d where e.deptno=d.deptno and e.sal between s.losal and s.hisal and s.grade>4;
顯示員工KING和FORD管理的員工姓名及其經(jīng)理姓名。
SELECT w.ename 員工姓名,m.ename 領導姓名 FROM emp w,emp m WHERE w.mgr = m.empno AND m.ename in ('KING','FORD');
顯示員工姓名,參加工作時間,經(jīng)理名,參加工作時間,要求參加時間比經(jīng)理早。
SELECT w.ename 員工姓名,w.hiredate 參加工作時間,m.ename 經(jīng)理名,m.hiredate 參加工作時間 FROM emp w,

