原文上傳到百度文庫,如今發現word文檔不便於閱讀,所以更改寫爲markdown形式。
1 建庫和建表:
1.1 創建數據庫:
create database lsydb1 default character set utf8;
use lsydb1;
1.2 創建表(dept):
create table dept (deptno int primary key, dname nvarchar(30), loc nvarchar(30)) default character set utf8;
1.3 創建表(emp):
create table emp ( empno int primary key, ename nvarchar(30), job nvarchar(30), mgr int , hiredate datetime, sal decimal(6.2), comm decimal(6.2), deptno int ,foreign key(deptno) references dept(deptno)) default character set utf8;
1.4 向dept表插入數據(先插dept再插emp):
insert into dept (deptno, dname, loc)
values (10, 'ACCOUNTING', 'NEW YORK'),
(20, 'RESEARCH', 'DALLAS'),
(30, 'SALES', 'CHICAGO'),
(40, 'OPERATIONS', 'BOSTON');
dept表如下:
+--------+------------+----------+
| deptno | dname | loc |
+--------+------------+----------+
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
+--------+------------+----------+
1.5 向emp表插入數據
insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values (7369,'SMITH','CLERK',7902,'1980-12-17',800.00,NULL,20);
insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values (7499,'ALLEN','SALESMAN',7698,'1981-2-20',1600,300,30);
insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values ( 7521, 'WARD', 'SALESMAN', 7698, '1981-2-22', 1250, 500, 30);
insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values ( 7566, 'JONES', 'MANAGER', 7839, '1981-4-2', 2975, null, 20);
insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values ( 7654, 'MARTIN', 'SALESMAN', 7698, '1981-9-28', 1250, 1400, 30);
insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values ( 7698, 'BLAKE', 'MANAGER', 7839, '1981-5-1', 2850, NULL, 30);
insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values ( 7782, 'CLARK', 'MANAGER', 7839, '1981-6-9', 2450, NULL, 10);
insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values ( 7788, 'SCOTT', 'ANALYST', 7566, '1987-4-19', 3000, NULL, 20);
insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values ( 7839, 'KING', 'PRESIDENT', NULL, '1981-11-17', 5000, NULL, 10);
insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values ( 7844, 'TURNER', 'SALESMAN', 7698, '1981-9-8', 1500, 0, 30);
insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values (7876, 'ADAMS', 'CLERK', 7788, '1987-5-23', 1100, NULL, 20);
insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values (7900, 'JAMES', 'CLERK', 7698, '1981-12-3', 950, NULL, 30);
insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values ( 7902, 'FORD', 'ANALYST', 7566, '1981-12-3', 3000, NULL, 20);
insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values (7934, 'MILLER', 'CLERK', 7782, '1982-1-23', 1300, NULL, 10);
emp表:
+-------+--------+-----------+------+---------------------+------+------+--------+
| empno | ename | job | mgr | hiredate | sal | comm | deptno |
+-------+--------+-----------+------+---------------------+------+------+--------+
| 7369 | SMITH | CLERK | 7902 | 1980-12-17 00:00:00 | 800 | NULL | 20 |
| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 00:00:00 | 1600 | 300 | 30 |
| 7521 | WARD | SALESMAN | 7698 | 1981-02-22 00:00:00 | 1250 | 500 | 30 |
| 7566 | JONES | MANAGER | 7839 | 1981-04-02 00:00:00 | 2975 | NULL | 20 |
| 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 00:00:00 | 1250 | 1400 | 30 |
| 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 00:00:00 | 2850 | NULL | 30 |
| 7782 | CLARK | MANAGER | 7839 | 1981-06-09 00:00:00 | 2450 | NULL | 10 |
| 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 00:00:00 | 3000 | NULL | 20 |
| 7839 | KING | PRESIDENT | NULL | 1981-11-17 00:00:00 | 5000 | NULL | 10 |
| 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 00:00:00 | 1500 | 0 | 30 |
| 7876 | ADAMS | CLERK | 7788 | 1987-05-23 00:00:00 | 1100 | NULL | 20 |
| 7900 | JAMES | CLERK | 7698 | 1981-12-03 00:00:00 | 950 | NULL | 30 |
| 7902 | FORD | ANALYST | 7566 | 1981-12-03 00:00:00 | 3000 | NULL | 20 |
| 7934 | MILLER | CLERK | 7782 | 1982-01-23 00:00:00 | 1300 | NULL | 10 |
+-------+--------+-----------+------+---------------------+------+------+--------+
2 基本查詢操作:
2.1 如何查詢工資在2000到2500的員工情況
select * from emp where sal> 2000 and sal < 2500;
select * from emp where sal between 2000 and 2500;
between是取兩邊的包括2000和2500.
2.2 模糊查詢:
顯示首字母爲S的員工的姓名和工資
select ename ,sal from emp where ename like “s%”;
2.3 顯示empno爲123,345,800..的僱員情況。
使用 in關鍵字效率更高。
Select * from emp where emono in (123,345,800);
3 複雜查詢操作:
3.1 顯示員工最低和最高工資。
select ename ,sal from emp where sal>= ( select max(sal) from emp) or sal<= (select min(sal) from emp);
3.2 顯示員工平均工資和總工資
select sum(sal),avg(sal) from emp;
3.3 顯示高於平均工作僱員的姓名和工資,並顯示平均工資。
select ename ,sal ,(select avg(sal) from emp) from emp where sal > (select avg(sal) from emp);
3.4 顯示員工人數:
select count(ename) from emp;
group by:用於查詢的結果分組統計。
having by:用於限制分組顯示結果。
3.5 顯示每個部門的平均工資和最高工資
mysql> select deptno,avg(sal) as "每個部門的平均工資" ,max(sal) as "每個部門的最高工資" from emp group by deptno;
結果下圖:
+--------+-----------------------------+-----------------------------+
| deptno | 每個部門的平均工資 | 每個部門的最高工資 |
+--------+-----------------------------+-----------------------------+
| 10 | 2916.6667 | 5000 |
| 20 | 2175.0000 | 3000 |
| 30 | 1566.6667 | 2850 |
+--------+-----------------------------+-----------------------------+
3.6 顯示每個部門的沒中崗位的平均工資和最低工資:
select avg(sal),min(sal) ,deptno,job from emp group by deptno,job;
結果圖:
+-----------+----------+--------+-----------+
| avg(sal) | min(sal) | deptno | job |
+-----------+----------+--------+-----------+
| 1300.0000 | 1300 | 10 | CLERK |
| 2450.0000 | 2450 | 10 | MANAGER |
| 5000.0000 | 5000 | 10 | PRESIDENT |
| 3000.0000 | 3000 | 20 | ANALYST |
| 950.0000 | 800 | 20 | CLERK |
| 2975.0000 | 2975 | 20 | MANAGER |
| 950.0000 | 950 | 30 | CLERK |
| 2850.0000 | 2850 | 30 | MANAGER |
| 1400.0000 | 1250 | 30 | SALESMAN |
3.7 顯示平均工資低於2000的部門和他的平均工資
(having
往往和group by
結合使用,可以對分組查詢結果進行篩選)
select avg(sal) ,deptno from emp group by deptno having avg(sal) < 2000 ;
4 複雜查詢(多表)
4.1 顯示僱員的名字和部門的地點:
select emp.ename,dept.loc from emp,dept where emp.deptno=dept.deptno and dept.dname="sales";
結果:
+--------+---------+
| ename | loc |
+--------+---------+
| ALLEN | CHICAGO |
| WARD | CHICAGO |
| MARTIN | CHICAGO |
| BLAKE | CHICAGO |
| TURNER | CHICAGO |
| JAMES | CHICAGO |
+--------+---------+
4.2 顯示部門號爲10的部門名,員工名和工資。
Select dept.dname,emp.ename,emp.sal from dept,emp where emp.deptno=dept.deptno and dept.deptno=10;
結果:
+------------+--------+------+
| dname | ename | sal |
+------------+--------+------+
| ACCOUNTING | CLARK | 2450 |
| ACCOUNTING | KING | 5000 |
| ACCOUNTING | MILLER | 1300 |
+------------+--------+------+
4.3 顯示僱員名,僱員工資及所在部門的名字,並按部門排序。
select emp.ename,emp.sal,dept.dname from emp,dept where emp.deptno=dept.deptno order by dept.dname;
結果:
+--------+------+------------+
| ename | sal | dname |
+--------+------+------------+
| CLARK | 2450 | ACCOUNTING |
| KING | 5000 | ACCOUNTING |
| MILLER | 1300 | ACCOUNTING |
| SMITH | 800 | RESEARCH |
| JONES | 2975 | RESEARCH |
| SCOTT | 3000 | RESEARCH |
| ADAMS | 1100 | RESEARCH |
| FORD | 3000 | RESEARCH |
| ALLEN | 1600 | SALES |
| WARD | 1250 | SALES |
| MARTIN | 1250 | SALES |
| BLAKE | 2850 | SALES |
| TURNER | 1500 | SALES |
| JAMES | 950 | SALES |
+--------+------+------------+
自連接:同一張表的連接查詢。
4.4 顯示某員工的上級領導的姓名,比如“FORD”的上級。
select ename from emp where empno=(select mgr from emp where ename="ford");
```
圖:
```shell
+-------+
| ename |
+-------+
| JONES |
+-------+
<div class="se-preview-section-delimiter"></div>
4.5 顯示公司每個員工名字和他上級的名字。
4.5.1 自連接。
select a.ename,b.ename from emp a,emp b where b.empno=a.mgr ;
<div class="se-preview-section-delimiter"></div>
結果:
+--------+-------+
| ename | ename |
+--------+-------+
| SMITH | FORD |
| ALLEN | BLAKE |
| WARD | BLAKE |
| JONES | KING |
| MARTIN | BLAKE |
| BLAKE | KING |
| CLARK | KING |
| SCOTT | JONES |
| TURNER | BLAKE |
| ADAMS | SCOTT |
| JAMES | BLAKE |
| FORD | JONES |
| MILLER | CLARK |
<div class="se-preview-section-delimiter"></div>
4.5.2 外鏈接(左和右)
4.6 顯示與SMITH同一部門的所有員工。(單行子查詢)
select * from emp where deptno=(select deptno from emp where ename="SMITH");
select * from emp where deptno in (select deptno from emp where ename="SMITH");
4.7 顯示和部門10的工作相同的僱員名字,崗位,工資和部門號。(多行子查詢)
(部門包括10)
select ename,job,sal,deptno from emp where job in (select distinct job from emp where deptno=10);
<div class="se-preview-section-delimiter"></div>
圖:
+--------+-----------+------+--------+
| ename | job | sal | deptno |
+--------+-----------+------+--------+
| SMITH | CLERK | 800 | 20 |
| JONES | MANAGER | 2975 | 20 |
| BLAKE | MANAGER | 2850 | 30 |
| CLARK | MANAGER | 2450 | 10 |
| KING | PRESIDENT | 5000 | 10 |
| ADAMS | CLERK | 1100 | 20 |
| JAMES | CLERK | 950 | 30 |
| MILLER | CLERK | 1300 | 10 |
+--------+-----------+------+--------+
<div class="se-preview-section-delimiter"></div>
(部門不包括10)
select ename,job,sal,deptno from emp where job in (select distinct job from emp where deptno=10) and deptno <> 10;
<div class="se-preview-section-delimiter"></div>
圖:
+-------+---------+------+--------+
| ename | job | sal | deptno |
+-------+---------+------+--------+
| SMITH | CLERK | 800 | 20 |
| JONES | MANAGER | 2975 | 20 |
| BLAKE | MANAGER | 2850 | 30 |
| ADAMS | CLERK | 1100 | 20 |
| JAMES | CLERK | 950 | 30 |
<div class="se-preview-section-delimiter"></div>
在from語句中使用子查詢。
4.8 顯示高於部門平均工資的員工信息。
select emp.ename,emp.sal,emp.deptno,tmp.myavg from emp,(select avg(sal) myavg ,deptno from emp group by deptno ) tmp where emp.sal>myavg and tmp.deptno=emp.deptno;
```
圖:
<div class="se-preview-section-delimiter"></div>
```sql
+-------+------+--------+-----------+
| ename | sal | deptno | myavg |
+-------+------+--------+-----------+
| KING | 5000 | 10 | 2916.6667 |
| JONES | 2975 | 20 | 2175.0000 |
| SCOTT | 3000 | 20 | 2175.0000 |
| FORD | 3000 | 20 | 2175.0000 |
| ALLEN | 1600 | 30 | 1566.6667 |
| BLAKE | 2850 | 30 | 1566.6667 |
+-------+------+--------+-----------+
```
## 4.9 顯示第5到第10入職僱員(按時間的先後)
```sql
select * from emp order by hiredate asc limit 4,7;
<div class="se-preview-section-delimiter"></div>
圖:
+-------+--------+-----------+------+---------------------+------+------+--------+
| empno | ename | job | mgr | hiredate | sal | comm | deptno |
+-------+--------+-----------+------+---------------------+------+------+--------+
| 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 00:00:00 | 2850 | NULL | 30 |
| 7782 | CLARK | MANAGER | 7839 | 1981-06-09 00:00:00 | 2450 | NULL | 10 |
| 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 00:00:00 | 1500 | 0 | 30 |
| 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 00:00:00 | 1250 | 1400 | 30 |
| 7839 | KING | PRESIDENT | NULL | 1981-11-17 00:00:00 | 5000 | NULL | 10 |
| 7902 | FORD | ANALYST | 7566 | 1981-12-03 00:00:00 | 3000 | NULL | 20 |
| 7900 | JAMES | CLERK | 7698 | 1981-12-03 00:00:00 | 950 | NULL | 30 |
<div class="se-preview-section-delimiter"></div>
4.10 左外連接和右外連接
- (左外連接) :左邊的表記錄全部顯示,如果沒有匹配記錄就顯示NULL
- (右外連接) :右邊的表記錄全部顯示,如果沒有匹配記錄就顯示NULL
例子如下圖:
4.11 顯示公司每位員工和他的上級名字,沒有上級的名字也要顯示。
select a.ename,b.ename from emp a left join emp b on a.mgr=b.empno;
<div class="se-preview-section-delimiter"></div>
圖:
+--------+-------+
| ename | ename |
+--------+-------+
| SMITH | FORD |
| ALLEN | BLAKE |
| WARD | BLAKE |
| JONES | KING |
| MARTIN | BLAKE |
| BLAKE | KING |
| CLARK | KING |
| SCOTT | JONES |
| KING | NULL |
| TURNER | BLAKE |
| ADAMS | SCOTT |
| JAMES | BLAKE |
| FORD | JONES |
| MILLER | CLARK |
+--------+-------+
<div class="se-preview-section-delimiter"></div>
5 題目看下圖:
5.1 先創建goods表。
create table goods (goodsId nvarchar(50) primary key, goodsName nvarchar(80) not null, unitPrice decimal(8,2) check(unitPrice > 0), category nvarchar(3) check(catagory in("食物","日用品")), provider nvarchar(50)) default character set utf8;
<div class="se-preview-section-delimiter"></div>
圖:
+-----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| goodsId | varchar(50) | NO | PRI | NULL | |
| goodsName | varchar(80) | NO | | NULL | |
| unitPrice | decimal(8,2) | YES | | NULL | |
| category | varchar(3) | YES | | NULL | |
| provider | varchar(50) | YES | | NULL | |
<div class="se-preview-section-delimiter"></div>
5.2 創建customer表:
create table customer (customerId nvarchar(50) primary key, custName nvarchar(50) not null, address nvarchar(100), email nvarchar(100) unique, sex nchar(1) default "男" check(sex in("男","女")) , cardId nvarchar(18) ) default character set utf8;
<div class="se-preview-section-delimiter"></div>
圖:
+------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+-------+
| customerId | varchar(50) | NO | PRI | NULL | |
| custName | varchar(50) | NO | | NULL | |
| address | varchar(100) | YES | | NULL | |
| email | varchar(100) | YES | UNI | NULL | |
| sex | char(1) | YES | | 男 | |
| cardId | varchar(18) | YES | | NULL | |
+------------+--------------+------+-----+---------+-------+
<div class="se-preview-section-delimiter"></div>
5.3 創建purchase表。
create table purchase (
customerId nvarchar(50) ,
goodsId nvarchar(50) ,
nums int check(nums>0) ,
CONSTRAINT `purchase_fk_customerId` FOREIGN KEY (`customerId`) REFERENCES `customer` (`customerId`),
CONSTRAINT `purchase_fk_goodsId'` FOREIGN KEY (`goodsId`) REFERENCES `goods` (`goodsId`)) default character set utf8;
<div class="se-preview-section-delimiter"></div>
圖:
+------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| customerId | varchar(50) | YES | MUL | NULL | |
| goodsId | varchar(50) | YES | MUL | NULL | |
| nums | int(11) | YES | | NULL | |
+------------+-------------+------+-----+---------+-------+
[原創]轉載請註明來自 韓順平的java入門到精通中serversql筆記(包括emp表和dept表,linux的mysql版)