MySQL查詢命令-DQL
目錄
MySQL查詢命令-DQL
EMP //員工表 員工編號 員工名 崗位 領導 入職日期 工資 獎金 部門編號 +-------+--------+-----------+------+------------+---------+---------+--------+ | EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO | +-------+--------+-----------+------+------------+---------+---------+--------+ | 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 | | 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 | | 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 | | 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 | | 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 | | 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 | | 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 | | 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 | | 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 | | 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 | | 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 | | 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 | | 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 | | 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 | +-------+--------+-----------+------+------------+---------+---------+--------+ 14 rows in set (0.00 sec) DEPT //員工部門表 部門編號 部門名 地址 +--------+------------+----------+ | DEPTNO | DNAME | LOC | +--------+------------+----------+ | 10 | ACCOUNTING | NEW YORK | | 20 | RESEARCH | DALLAS | | 30 | SALES | CHICAGO | | 40 | OPERATIONS | BOSTON | +--------+------------+----------+ 4 rows in set (0.00 sec) SALGRADE //工資等級表 等級 最少 最高 +-------+-------+-------+ | GRADE | LOSAL | HISAL | +-------+-------+-------+ | 1 | 700 | 1200 | | 2 | 1201 | 1400 | | 3 | 1401 | 2000 | | 4 | 2001 | 3000 | | 5 | 3001 | 9999 | +-------+-------+-------+ 5 rows in set (0.00 sec)
常用命令
登入 mysql -uroot -p密碼 檢視全部資料庫 show databases; 建立資料庫 create database 資料庫名 進入(使用)資料庫 use 資料庫名 檢視當前使用的資料庫中的所有表 show tables; 初始化資料 source 資料庫檔案地址(例如: source D: \XiaoK. sq1) 刪除資料庫 drop database 資料庫名 查看錶結構 desc 表名 檢視當前使用的是哪個資料庫 select database(); 檢視資料庫版本 select version(); 終止語句 \c 查詢表的全部內容 select * from 表名 檢視其中庫中的表 show tables from exam; 檢視建立表的語句 show create table 表名; 如果表存在則刪除此表 drop table if exists 表名;
一個完整的DQL語句
select 5
...
from 1
...
where 2
...
group by 3
...
having 4
...
order by 6
...
limit 7
...
查詢
簡單的查詢語句
select 欄位名1,欄位名2,... from 表名;
案例1:查詢所有欄位
mysql> select * from emp; +-------+--------+-----------+------+------------+---------+---------+--------+ | EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO | +-------+--------+-----------+------+------------+---------+---------+--------+ | 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 | | 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 | | 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 | | 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 | | 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 | | 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 | | 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 | | 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 | | 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 | | 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 | | 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 | | 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 | | 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 | | 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 | +-------+--------+-----------+------+------------+---------+---------+--------+ 14 rows in set (0.01 sec)
案例2:查詢員工的年薪
mysql> select ename,sal*12 from emp;
+--------+----------+
| ename | sal*12 |
+--------+----------+
| SMITH | 9600.00 |
| ALLEN | 19200.00 |
| WARD | 15000.00 |
| JONES | 35700.00 |
| MARTIN | 15000.00 |
| BLAKE | 34200.00 |
| CLARK | 29400.00 |
| SCOTT | 36000.00 |
| KING | 60000.00 |
| TURNER | 18000.00 |
| ADAMS | 13200.00 |
| JAMES | 11400.00 |
| FORD | 36000.00 |
| MILLER | 15600.00 |
+--------+----------+
14 rows in set (0.00 sec)
案例3:給查詢結果的列重新命名
其中如果需要更改所查詢的欄位名則使用一下語句
select ename,sal*12 as yearsal from emp;
其中as也可省略,如果更改的欄位名為中文則使用單引號括起來
條件查詢
select 欄位1,欄位2,... from 表名 where 條件;
運算子 | 說明 |
---|---|
= | 等於 |
<>或!= | 不等於 |
< | 小於 |
<= | 小於等於 |
> | 大於 |
>= | 大於等於 |
between...and... | 兩個值之間,等同於>= and <= |
is null | 為null(is not null不為空) |
and | 並且 |
or | 或者 |
in | 包含,相當於多個or(not in 不在這個範圍中) |
not | not可以取非,主要用在is或in中 |
like | like稱為模糊查詢,支援%或者下劃線匹配 |
案例1:找出哪些人津貼為NULL
在資料庫中null不是一個值,不能用等號衡量,使用語法是 is null 或 is not null
mysql> select ename,comm from emp where comm is null;
+--------+------+
| ename | comm |
+--------+------+
| SMITH | NULL |
| JONES | NULL |
| BLAKE | NULL |
| CLARK | NULL |
| SCOTT | NULL |
| KING | NULL |
| ADAMS | NULL |
| JAMES | NULL |
| FORD | NULL |
| MILLER | NULL |
+--------+------+
10 rows in set (0.00 sec)
案例2:找出哪些人津貼不為NULL
mysql> select ename,comm from emp where comm is not null;
+--------+---------+
| ename | comm |
+--------+---------+
| ALLEN | 300.00 |
| WARD | 500.00 |
| MARTIN | 1400.00 |
| TURNER | 0.00 |
+--------+---------+
4 rows in set (0.00 sec)
案例3:找出哪些人沒有津貼
mysql> select ename,comm from emp where comm is null or comm = 0;
+--------+------+
| ename | comm |
+--------+------+
| SMITH | NULL |
| JONES | NULL |
| BLAKE | NULL |
| CLARK | NULL |
| SCOTT | NULL |
| KING | NULL |
| TURNER | 0.00 |
| ADAMS | NULL |
| JAMES | NULL |
| FORD | NULL |
| MILLER | NULL |
+--------+------+
11 rows in set (0.00 sec)
案例4:找出工作崗位是manager和salesman的員工
mysql> select ename,job from emp where job = 'manager' or job = 'salesman';
+--------+----------+
| ename | job |
+--------+----------+
| ALLEN | SALESMAN |
| WARD | SALESMAN |
| JONES | MANAGER |
| MARTIN | SALESMAN |
| BLAKE | MANAGER |
| CLARK | MANAGER |
| TURNER | SALESMAN |
+--------+----------+
7 rows in set (0.00 sec)
案例5:找出薪資大於1000的並且部門編號是20或30部門的員工
mysql> select ename,sal,deptno from emp where sal > 1000 and (deptno = 20 or deptno = 30);
+--------+---------+--------+
| ename | sal | deptno |
+--------+---------+--------+
| ALLEN | 1600.00 | 30 |
| WARD | 1250.00 | 30 |
| JONES | 2975.00 | 20 |
| MARTIN | 1250.00 | 30 |
| BLAKE | 2850.00 | 30 |
| SCOTT | 3000.00 | 20 |
| TURNER | 1500.00 | 30 |
| ADAMS | 1100.00 | 20 |
| FORD | 3000.00 | 20 |
+--------+---------+--------+
9 rows in set (0.00 sec)
案例6:找出工作崗位是manager和salesman的員工,使用in
在這裡in等同於or
mysql> select ename,job from emp where job in ('manager','salesman');
+--------+----------+
| ename | job |
+--------+----------+
| ALLEN | SALESMAN |
| WARD | SALESMAN |
| JONES | MANAGER |
| MARTIN | SALESMAN |
| BLAKE | MANAGER |
| CLARK | MANAGER |
| TURNER | SALESMAN |
+--------+----------+
7 rows in set (0.00 sec)
案例7:找出工資不是800和5000的所有人
這裡使用的是 not in
mysql> select ename,sal from emp where sal not in (800,5000);
+--------+---------+
| ename | sal |
+--------+---------+
| ALLEN | 1600.00 |
| WARD | 1250.00 |
| JONES | 2975.00 |
| MARTIN | 1250.00 |
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
| SCOTT | 3000.00 |
| TURNER | 1500.00 |
| ADAMS | 1100.00 |
| JAMES | 950.00 |
| FORD | 3000.00 |
| MILLER | 1300.00 |
+--------+---------+
12 rows in set (0.00 sec)
同樣可以用
mysql> select ename,sal from emp where sal<>800 and sal<>5000;
模糊查詢
在模糊查詢中,有兩個特殊的符號,一個是%,一個是_
%代表任意多個字元,_代表任意1個字元
案例1:找出名字中含有O的
mysql> select ename from emp where ename like '%o%';
+-------+
| ename |
+-------+
| JONES |
| SCOTT |
| FORD |
+-------+
3 rows in set (0.00 sec)
案例2:找出名字中第二個字母是o的
mysql> select ename from emp where ename like '_o%';
+-------+
| ename |
+-------+
| JONES |
| FORD |
+-------+
2 rows in set (0.00 sec)
同理:找出名字中第三個字母是o的可得
select ename from emp where ename like '_ _o%';
案例3:找出名字中有下劃線的
select ename from emp where ename like '%\_%';
使用轉義字元
排序
案例1:按照工資升序,找出員工名和薪資
這裡使用到了 order by 預設是升序排列
如何指定是升序或者是降序呢?asc表示升序,desc表示降序
mysql> select ename,sal from emp order by sal asc;
+--------+---------+
| ename | sal |
+--------+---------+
| SMITH | 800.00 |
| JAMES | 950.00 |
| ADAMS | 1100.00 |
| WARD | 1250.00 |
| MARTIN | 1250.00 |
| MILLER | 1300.00 |
| TURNER | 1500.00 |
| ALLEN | 1600.00 |
| CLARK | 2450.00 |
| BLAKE | 2850.00 |
| JONES | 2975.00 |
| FORD | 3000.00 |
| SCOTT | 3000.00 |
| KING | 5000.00 |
+--------+---------+
14 rows in set (0.00 sec)
如果需要讓他降序排列則
select ename,sal from emp order by sal desc;
案例2:按照工資的降序排列,當工資相同的時候再按照名字的升序排列。
mysql> select ename,sal from emp order by sal desc,ename asc;
+--------+---------+
| ename | sal |
+--------+---------+
| KING | 5000.00 |
| FORD | 3000.00 |
| SCOTT | 3000.00 |
| JONES | 2975.00 |
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
| ALLEN | 1600.00 |
| TURNER | 1500.00 |
| MILLER | 1300.00 |
| MARTIN | 1250.00 |
| WARD | 1250.00 |
| ADAMS | 1100.00 |
| JAMES | 950.00 |
| SMITH | 800.00 |
+--------+---------+
14 rows in set (0.00 sec)
注意:越靠前的欄位越能起到主導作用,只有當前面的欄位無法起到排序的時候,才會啟用後面的欄位
排序order by也可以使用者按列
案例3:找出工作崗位是salesman的員工,並且要求按照薪資的降序排列
mysql> select ename,sal,job from emp where job='salesman' order by sal desc;
+--------+---------+----------+
| ename | sal | job |
+--------+---------+----------+
| ALLEN | 1600.00 | SALESMAN |
| TURNER | 1500.00 | SALESMAN |
| WARD | 1250.00 | SALESMAN |
| MARTIN | 1250.00 | SALESMAN |
+--------+---------+----------+
4 rows in set (0.00 sec)
執行順序
select
* 3
from
表名 1
where
條件 2
order by
..... 4
order by 是最後執行的
分組函式
分組函式一共有5個
分組函式還有另一個名字:多行處理函式
多行處理函式的特點:輸入多行,最終輸出的結果是1行
分組函式自動忽略null,不需要ifnull函式
count | 計數 |
---|---|
sum | 求和 |
avg | 取平均值 |
min | 取最小值 |
max | 取最大值 |
案例1:找出員工工資總和
mysql> select sum(sal) from emp;
+----------+
| sum(sal) |
+----------+
| 29025.00 |
+----------+
1 row in set (0.00 sec)
案例2:找出最高工資
select max(sal) from emp;
案例3:找出最低工資
select min(sal) from emp;
案例4:找出平均工資
select avg(sal) from emp;
案例5:找出總人數
select count(*) from emp;
select count(ename) from emp;
分組函式自動忽略NULL
mysql> select count(comm) from emp;
+-------------+
| count(comm) |
+-------------+
| 4 |
+-------------+
1 row in set (0.00 sec)
單行處理函式
什麼是單行處理函式?
輸入一行,輸出一行
案例:計算每個員工的年薪
select ename , (sal+comm) * 12 from emp;
結果出現:
mysql> select ename,(sal+comm)*12 from emp;
+--------+---------------+
| ename | (sal+comm)*12 |
+--------+---------------+
| SMITH | NULL |
| ALLEN | 22800.00 |
| WARD | 21000.00 |
| JONES | NULL |
| MARTIN | 31800.00 |
| BLAKE | NULL |
| CLARK | NULL |
| SCOTT | NULL |
| KING | NULL |
| TURNER | 18000.00 |
| ADAMS | NULL |
| JAMES | NULL |
| FORD | NULL |
| MILLER | NULL |
+--------+---------------+
14 rows in set (0.00 sec)
重點:所有資料庫規定,只要有NULL參與運算的結果一定是NULL 例:1000+null = null
ifnull() 空處理函式
ifnull(可能為NULL的資料,被當做什麼處理),屬於單行處理函式
所以可解決以上問題
mysql> select ename,(sal+ifnull(comm,0))*12 from emp;
+--------+-------------------------+
| ename | (sal+ifnull(comm,0))*12 |
+--------+-------------------------+
| SMITH | 9600.00 |
| ALLEN | 22800.00 |
| WARD | 21000.00 |
| JONES | 35700.00 |
| MARTIN | 31800.00 |
| BLAKE | 34200.00 |
| CLARK | 29400.00 |
| SCOTT | 36000.00 |
| KING | 60000.00 |
| TURNER | 18000.00 |
| ADAMS | 13200.00 |
| JAMES | 11400.00 |
| FORD | 36000.00 |
| MILLER | 15600.00 |
+--------+-------------------------+
14 rows in set (0.00 sec)
案例:找出工資高於平均工資的員工?
會出現以下錯誤
mysql> select ename,sal from emp where sal > avg(sal);
ERROR 1111 (HY000): Invalid use of group function
mysql> select ename,sal from emp where sal > (select avg(sal) from emp);
+-------+---------+
| ename | sal |
+-------+---------+
| JONES | 2975.00 |
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
| SCOTT | 3000.00 |
| KING | 5000.00 |
| FORD | 3000.00 |
+-------+---------+
6 rows in set (0.00 sec)
注意:分組函式不能直接使用在where語句中
count(*)和count(具體的某個欄位),他們有什麼區別?
count(*):不是統計某個欄位中資料的個數,而是統計總記錄條數
count(sal):表示統計sal欄位中不為NULL的資料總數量。
group by 和 having
注意:分組函式一般都會和group by 聯合使用,並且任何一個分組函式(count sum avg max min)都是在group by語句執行結束之後才會執行,當一條sql語句沒有group by,整張表的資料就會自成一組。
group by : 按照某個欄位或者某些欄位進行分組。
having : having是對分組以後的資料進行再次過濾
案例:找出每個工作崗位的最高薪資
mysql> select ename,job,max(sal) from emp group by job;
+-------+-----------+----------+
| ename | job | max(sal) |
+-------+-----------+----------+
| SCOTT | ANALYST | 3000.00 |
| SMITH | CLERK | 1300.00 |
| JONES | MANAGER | 2975.00 |
| KING | PRESIDENT | 5000.00 |
| ALLEN | SALESMAN | 1600.00 |
+-------+-----------+----------+
5 rows in set (0.00 sec)
以上在mysql 當中,查詢結果是有的,但是結果沒有意義,在Oracle資料庫當中會報錯,語法錯誤,Oracle的語法規則比MySQL語法規則嚴謹。
記住一個規則:當一條語句中有group by的話,select後面只能跟分組函式和參與分組的欄位。
案例:每個工作崗位的平均薪資?
select job,avg(sal) from emp group by job;
多個欄位能不能聯合起來一塊分組?
案例:找出每個部門不同工作崗位的最高薪資?
mysql> select job,deptno,max(sal) from emp group by deptno,job;
+-----------+--------+----------+
| job | deptno | max(sal) |
+-----------+--------+----------+
| CLERK | 10 | 1300.00 |
| MANAGER | 10 | 2450.00 |
| PRESIDENT | 10 | 5000.00 |
| ANALYST | 20 | 3000.00 |
| CLERK | 20 | 1100.00 |
| MANAGER | 20 | 2975.00 |
| CLERK | 30 | 950.00 |
| MANAGER | 30 | 2850.00 |
| SALESMAN | 30 | 1600.00 |
+-----------+--------+----------+
9 rows in set (0.00 sec)
案例:找出每個部門的最高薪資,要求顯示薪資大於2900的資料
第一步:找出每個部門的最高薪資
select max(sal),deptno from emp group by deptno;
第二步:找出薪資大於2900
select max(sal),deptno from emp group by deptno having max(sal) > 2900;
//這種方式效率低,不推薦
mysql> select max(sal),deptno from emp where sal>2900 group by deptno;
+----------+--------+
| max(sal) | deptno |
+----------+--------+
| 5000.00 | 10 |
| 3000.00 | 20 |
+----------+--------+
2 rows in set (0.00 sec)
案例:找出每個部門的平均薪資,要求顯示薪資大於2000的資料
mysql> select avg(sal),deptno from emp group by deptno having avg(sal) > 2000;
+-------------+--------+
| avg(sal) | deptno |
+-------------+--------+
| 2916.666667 | 10 |
| 2175.000000 | 20 |
+-------------+--------+
2 rows in set (0.00 sec)
select deptno,avg(sal) from emp where avg(sal) >2000 group by deptno;
//這樣是錯誤的
去重 distinct
1、關於查詢結果集的去重?
distinct關鍵字去除重複記錄
mysql> select distinct job from emp;
+-----------+
| job |
+-----------+
| CLERK |
| SALESMAN |
| MANAGER |
| ANALYST |
| PRESIDENT |
+-----------+
5 rows in set (0.00 sec)
select ename,distinct job from job;
//這樣的sql語句是錯誤的
記住:distinct只能出現所有欄位的最前面,如果出現在最前面則表示後面所有聯合起來的欄位去重
案例:統計崗位的數量?
mysql> select count(distinct job) from emp;
+---------------------+
| count(distinct job) |
+---------------------+
| 5 |
+---------------------+
1 row in set (0.00 sec)
連線查詢
表的連線方式劃分:
- 內連線
- 等值連線
- 非等值連線
- 自連線
- 外連線
- 左外連線(左連線)
- 右外連線(右連線)
- 全連線
mysql> select ename,dname from emp,dept;
+--------+------------+
| ename | dname |
+--------+------------+
| SMITH | ACCOUNTING |
| SMITH | RESEARCH |
| SMITH | SALES |
| SMITH | OPERATIONS |
| ALLEN | ACCOUNTING |
| ALLEN | RESEARCH |
| ALLEN | SALES |
| ALLEN | OPERATIONS |
| WARD | ACCOUNTING |
| WARD | RESEARCH |
| WARD | SALES |
| WARD | OPERATIONS |
...
**關於表的別名:**
select e.ename,d.dname from emp e ,dept d;
好處:一、執行效率高 二、可讀性好
**案例:找出每一個員工的部門名稱,要求顯示員工的員工名和部門名稱**
mysql> select e.ename,d.dname from emp e,dept d where e.deptno = d.deptno;
//SQL92 語句已經過時,不使用
內連線
內連線:假設A和B表進行連線,使用內連線的話,凡是A表和B表能夠匹配上的記錄查詢出來,這就是內連線。
AB兩張表沒有主副之分,兩張表是平等的。
語法:
select
...
from
...
inner join //其中的inner是可以省略不寫的
...
on
...
等值連線
特點:條件是等量關係。
案例:查詢每個員工的部門名稱,要求顯示員工名和部門名。
SQL99 (常用的)
語法:
select
...
form
...
join
...
on //類似where 後面跟的是條件
...
也可 join ... inner ...
mysql> select e.ename,d.dname from emp e,dept d where e.deptno=d.deptno;(SQL92 過時的)
mysql> select e.ename,d.dname from emp e join dept d on e.deptno=d.deptno;(SQL99 常用)
+--------+------------+
| ename | dname |
+--------+------------+
| CLARK | ACCOUNTING |
| KING | ACCOUNTING |
| MILLER | ACCOUNTING |
| SMITH | RESEARCH |
| JONES | RESEARCH |
| SCOTT | RESEARCH |
| ADAMS | RESEARCH |
| FORD | RESEARCH |
| ALLEN | SALES |
| WARD | SALES |
| MARTIN | SALES |
| BLAKE | SALES |
| TURNER | SALES |
| JAMES | SALES |
+--------+------------+
14 rows in set (0.00 sec)
非等值連線
特點:連線條件中的關係是非等值關係
案例:找出每個員工的工資等級,要求顯示員工名、工資、工資等級。
mysql> select e.ename,e.sal,s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal;
+--------+---------+-------+
| ename | sal | grade |
+--------+---------+-------+
| SMITH | 800.00 | 1 |
| ALLEN | 1600.00 | 3 |
| WARD | 1250.00 | 2 |
| JONES | 2975.00 | 4 |
| MARTIN | 1250.00 | 2 |
| BLAKE | 2850.00 | 4 |
| CLARK | 2450.00 | 4 |
| SCOTT | 3000.00 | 4 |
| KING | 5000.00 | 5 |
| TURNER | 1500.00 | 3 |
| ADAMS | 1100.00 | 1 |
| JAMES | 950.00 | 1 |
| FORD | 3000.00 | 4 |
| MILLER | 1300.00 | 2 |
+--------+---------+-------+
14 rows in set (0.00 sec)
自連線
特點:一張表看作兩張表,自己連線自己。
案例:找出每個員工的上級領導,要求顯示員工名和對應的領導名
語法:
select
a.ename,b.ename
from
emp a
join
emp b
on
a.mgr = b.empno;
-------------------------------
mysql> select a.ename as '員工',b.ename as '領導' from emp a join emp b on a.mgr = b.empno;
+--------+-------+
| 員工 | 領導 |
+--------+-------+
| 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 |
+--------+-------+
13 rows in set (0.00 sec)
//因為KING對應的領導是NULL所以匹配不到
外連線
外連線:假設A和B表進行連線,使用外連線的話,AB兩張表中有一張表是主表,一張表是副表,主要查詢主表中的資料,捎帶著查詢副表,當副表中的資料沒有和主表中的資料匹配上,副標自動模擬出NULL與之匹配。
- 外連線的分類
- 左外連線(左連線):表示座標的這張表是主表
- 右外連線(右連線):表示右邊的這張表是主表
語法:
select
...
from
...
left/right outer join //其中的outer是可以省略不寫的
...
on
...
案例:找出每個員工的上級領導
mysql> select
-> a.ename emp,b.ename boss
-> from
-> emp a
-> left join
-> emp b
-> on
-> a.mgr=b.empno;
+--------+-------+
| emp | boss |
+--------+-------+
| 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 |
+--------+-------+
14 rows in set (0.00 sec)
案例:找出哪個部門沒有員工?
mysql> select d.* from emp e right join dept d on e.deptno=d.deptno where e.ename is null;
+--------+------------+--------+
| DEPTNO | DNAME | LOC |
+--------+------------+--------+
| 40 | OPERATIONS | BOSTON |
+--------+------------+--------+
1 row in set (0.00 sec)
同樣可一使用以下方法
mysql> select d.dname,count(e.ename) from emp e right outer join dept d on e.deptno=d.deptno group by dname;
+------------+----------------+
| dname | count(e.ename) |
+------------+----------------+
| ACCOUNTING | 3 |
| OPERATIONS | 0 |
| RESEARCH | 5 |
| SALES | 6 |
+------------+----------------+
4 rows in set (0.00 sec)
三張表怎麼連線查詢?
案例:找出每一個員工的部門名稱以及工資等級
格式:
select
e.ename,d.dname,s.grade
from
emp e
join
dept d
on
e.deptno=d.deptno
join
salgrade s
on
e.sal between s.losal and s.hisal;
結果:
+--------+------------+-------+
| ename | dname | grade |
+--------+------------+-------+
| SMITH | RESEARCH | 1 |
| ALLEN | SALES | 3 |
| WARD | SALES | 2 |
| JONES | RESEARCH | 4 |
| MARTIN | SALES | 2 |
| BLAKE | SALES | 4 |
| CLARK | ACCOUNTING | 4 |
| SCOTT | RESEARCH | 4 |
| KING | ACCOUNTING | 5 |
| TURNER | SALES | 3 |
| ADAMS | RESEARCH | 1 |
| JAMES | SALES | 1 |
| FORD | RESEARCH | 4 |
| MILLER | ACCOUNTING | 2 |
+--------+------------+-------+
14 rows in set (0.00 sec)
案例:找出每一個員工的部門名稱、工資等級、以及上級領導。
select
e.ename,d.dname,s.grade,a.ename
from
emp e
join
dept d
on
e.deptno=d.deptno
join
salgrade s
on
e.sal between s.losal and s.hisal
left join
emp a
on
e.mgr=a.empno;
結果:
+--------+------------+-------+-------+
| ename | dname | grade | ename |
+--------+------------+-------+-------+
| SMITH | RESEARCH | 1 | FORD |
| ALLEN | SALES | 3 | BLAKE |
| WARD | SALES | 2 | BLAKE |
| JONES | RESEARCH | 4 | KING |
| MARTIN | SALES | 2 | BLAKE |
| BLAKE | SALES | 4 | KING |
| CLARK | ACCOUNTING | 4 | KING |
| SCOTT | RESEARCH | 4 | JONES |
| KING | ACCOUNTING | 5 | NULL |
| TURNER | SALES | 3 | BLAKE |
| ADAMS | RESEARCH | 1 | SCOTT |
| JAMES | SALES | 1 | BLAKE |
| FORD | RESEARCH | 4 | JONES |
| MILLER | ACCOUNTING | 2 | CLARK |
+--------+------------+-------+-------+
14 rows in set (0.00 sec)
子查詢
什麼是子查詢?子查詢都可以出現在哪裡?
子查詢可以出現在哪裡?
select
...(select)
form
...(select)
where
...(select)
where子句中使用子查詢
案例:找出高於平均薪資的員工的資訊
select * from emp where sal>(select avg(sal) from emp);
from後面巢狀子查詢
案例:找出每個部門平均薪水的薪資等級。
第一步:先找出每個部門平均薪水的薪資等級
mysql> select deptno,avg(sal) from emp group by deptno;
+--------+-------------+
| deptno | avg(sal) |
+--------+-------------+
| 10 | 2916.666667 |
| 20 | 2175.000000 |
| 30 | 1566.666667 |
+--------+-------------+
3 rows in set (0.00 sec)
第二步:將以上查詢的結果當做臨時表t,讓t表和salgrade s表連線,條件是:t.avgsal between s.losal and s.hisal
mysql> select
-> t.deptno,t.avgsal,s.grade
-> from
-> (select deptno,avg(sal) avgsal from emp group by deptno) t
-> join
-> salgrade s
-> on
-> avgsal between s.losal and s.hisal;
+--------+-------------+-------+
| deptno | avgsal | grade |
+--------+-------------+-------+
| 30 | 1566.666667 | 3 |
| 10 | 2916.666667 | 4 |
| 20 | 2175.000000 | 4 |
+--------+-------------+-------+
3 rows in set (0.00 sec)
案例:找出每個部門平均的薪水等級
第一步:找出每個員工的薪水等級。
mysql> select e.ename,e.sal,e.deptno,s.grade from emp e join salgrade s on e.sal between s.losal and
s.hisal;
+--------+---------+--------+-------+
| ename | sal | deptno | grade |
+--------+---------+--------+-------+
| SMITH | 800.00 | 20 | 1 |
| ALLEN | 1600.00 | 30 | 3 |
| WARD | 1250.00 | 30 | 2 |
| JONES | 2975.00 | 20 | 4 |
| MARTIN | 1250.00 | 30 | 2 |
| BLAKE | 2850.00 | 30 | 4 |
| CLARK | 2450.00 | 10 | 4 |
| SCOTT | 3000.00 | 20 | 4 |
| KING | 5000.00 | 10 | 5 |
| TURNER | 1500.00 | 30 | 3 |
| ADAMS | 1100.00 | 20 | 1 |
| JAMES | 950.00 | 30 | 1 |
| FORD | 3000.00 | 20 | 4 |
| MILLER | 1300.00 | 10 | 2 |
+--------+---------+--------+-------+
14 rows in set (0.00 sec)
第二步:基於以上結果,繼續按照deptno分組,求grade平均值
mysql> select e.deptno,avg(s.grade)
-> from emp e
-> join salgrade s
-> on e.sal between s.losal and s.hisal
-> group by e.deptno;
+--------+--------------+
| deptno | avg(s.grade) |
+--------+--------------+
| 10 | 3.6667 |
| 20 | 2.8000 |
| 30 | 2.5000 |
+--------+--------------+
3 rows in set (0.00 sec)
在select後面巢狀子查詢
案例:找出每個員工所在的部門名稱,要求顯示員工名和部門名
mysql> select
-> e.ename,(select d.dname from dept d where e.deptno=d.deptno) as dname
-> from emp e;
+--------+------------+
| ename | dname |
+--------+------------+
| SMITH | RESEARCH |
| ALLEN | SALES |
| WARD | SALES |
| JONES | RESEARCH |
| MARTIN | SALES |
| BLAKE | SALES |
| CLARK | ACCOUNTING |
| SCOTT | RESEARCH |
| KING | ACCOUNTING |
| TURNER | SALES |
| ADAMS | RESEARCH |
| JAMES | SALES |
| FORD | RESEARCH |
| MILLER | ACCOUNTING |
+--------+------------+
14 rows in set (0.00 sec)
union
可以將查詢結果集相加
案例:找出工作崗位是SALESMAN和MANAGER的員工?
第一種:select ename,job from emp where job='salesman' or job='manager';
第二種:select ename,job from emp where job in ('salesman','manager');
第三種:union
select ename,job from emp where job='manager'
union
select ename,job from emp where job='salesman';
union可以實現把兩張不相干的表中的資料拼接在一起顯示,前提必須是要顯示相同的列數
例如:把員工名和部門名拼接在一塊顯示
mysql> select ename from emp
-> union
-> select dname from dept;
+------------+
| ename |
+------------+
| SMITH |
| ALLEN |
| WARD |
| JONES |
| MARTIN |
| BLAKE |
| CLARK |
| SCOTT |
| KING |
| TURNER |
| ADAMS |
| JAMES |
| FORD |
| MILLER |
| ACCOUNTING |
| RESEARCH |
| SALES |
| OPERATIONS |
+------------+
18 rows in set (0.00 sec)
limit ★
limit:取結果集中的部分資料。
limit是MySQL特有的,其他資料庫中沒有,不通用。(Oracle中有一個相同的機制,叫做rownum)
limit是sql語句最後執行的一個環節
語法:limit startIndex,length
startIndex表示起始位置,可以省略不寫,預設為0
length表示取幾個
案例:取出工資前5名的員工(思路:降序取前5個)
mysql> select ename,sal from emp order by sal desc limit 0,5;
+-------+---------+
| ename | sal |
+-------+---------+
| KING | 5000.00 |
| SCOTT | 3000.00 |
| FORD | 3000.00 |
| JONES | 2975.00 |
| BLAKE | 2850.00 |
+-------+---------+
5 rows in set (0.00 sec)
案例:找出工資排名在第4到第9名的員工?
mysql> select ename,sal from emp order by sal desc limit 3,6;
+--------+---------+
| ename | sal |
+--------+---------+
| JONES | 2975.00 |
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
| ALLEN | 1600.00 |
| TURNER | 1500.00 |
| MILLER | 1300.00 |
+--------+---------+
6 rows in set (0.00 sec)
通用標準分頁sql
每頁顯示5條記錄:
第1頁:0, 5
第2頁:5, 5
第3頁:10,5
第4頁:15,5
第5頁:20,5
...
所以可得:每頁顯示pageSize條記錄:
第pageNo頁:(pageNo - 1) * pageSize , pageSize
pageSize : 代表每頁顯示多少條記錄
pageNo : 代表顯示第幾頁
java程式碼{
int pageNo = 2;//頁碼是2
int pageSize = 10;//每頁顯示10條
limit (pageNo - 1) * pageSize , pageSize;
}