mysql查詢(分組查詢、連接查詢、子查詢)

mysql查詢

一、分組查詢

1、分組查詢設計的兩個字句:

- group by
- having 

2、group by

2.1 order by 【表示通過哪個或者哪些字段進行排序】

group by 【表示通過哪個或者哪些字段進行分組】

2.2 案例:找出每個工作崗位的最高薪水【先按照工作崗位分組,使用max函數求每一組的最高薪水】

select 
	 max(sal)
from
  	emp
group by
 	 job;

以上語句,先按照job分組,然後對每一組使用max(sal)求最高薪水

select 
	 job,max(sal)
from
  	emp
group by
 	 job;

重點:若一條DQL語句中有group by 字句,那麼select關鍵字後面只能跟參與分組的字段和分組函數。

2.3 案例:計算每個部門的平均薪水【按部門編號分組,對每一組求平均薪水】

select deptno,avg(sal) as avgsal from emp group by deptno;

±-------±------------+
| deptno | avgsal |
±-------±------------+
| 20 | 2175.000000 |
| 30 | 1566.666667 |
| 10 | 2916.666667 |
±-------±------------+

2.4 案例:計算不同部門不同崗位的最高薪水

 select deptno,job,max(sal) from emp group by deptno,job;

2.5 案例:找出每個崗位的最高薪水,除去崗位爲 MANAGER 的部分。

 select job,max(sal) from emp where job<>'MANAGER' group by job;

3、having

having和where功能相同,都是爲了 完成數據的過濾。兩者後面都是添加條件。
where在group by 之前完成過濾;
having在group by之後完成過濾。

3.1案例:找出每個工作崗位的平均薪水。要求顯示平均薪水大於1500。

select job,avg(sal) from emp where avg(sal)>1500 group by job;
  ERROR 1111 (HY000): Invalid use of group function
  原因:where關鍵字後面不能直接使用分組函數,分組函數必須在分組完成後執行
 mysql> select job,avg(sal) from emp  group by job having avg(sal)>1500;

±----------±------------+
| job | avg(sal) |
±----------±------------+
| MANAGER | 2758.333333 |
| ANALYST | 3000.000000 |
| PRESIDENT | 5000.000000 |
±----------±------------+
原則:由於兩個函數的效率不同問題,儘量在where 中過濾,無法過濾的數據,通常先分組之後在過濾,這時候可以選擇使用having。

4、 一個完整的DQL語句總結:

select…
from …
where…
group by …
having …
order by…

第一:以上的關鍵字順序不能變,嚴格遵守
第二:執行順序:
1、from 從某張表中檢索數據
2、where 經過某條件進行過濾
3、group by 然後分組
4、having 分組之後不滿意的在過濾
5、select查詢出來
6、order by 排序輸出

二、連接查詢

1、連接查詢根據出現的年代分類:

-sql92
-sql99【主要掌握】

2、連接查詢根據連接方式分類:

-內連接: 等值連接 \ 非等值連接 \ 自連接
-外連接:左外連接\右外鏈接
-全連接【使用很少】

3、當多張表進行連接查詢,若沒有任何條件進行限制,會發生什麼現象?

案例:查詢每一個員工所在部門的名稱,要求最終顯示員工名和對應部門名。
emp 員工表
±-------±-------+
| ename | deptno |
±-------±-------+
| SIMITH | 20 |
| ALLEN | 30 |
| WARD | 30 |
| JONES | 20 |
| MARTIN | 30 |
| BLAKE | 30 |
| CLARK | 10 |
| SCOTT | 20 |
| KING | 10 |
| TURNER | 30 |
| ADAMS | 20 |
| JAMES | 30 |
| FORD | 20 |
| MILLER | 10 |
±-------±-------+

dept部門表
±-------±------------+
| deptno | dname |
±-------±------------+
| 10 | ACCOUNTING |
| 20 | RESEARCHING |
| 30 | SALES |
| 40 | OPERATIONS |
±-------±------------+
主要分析:多張表連接查詢,若沒有任何條件進行限制,會發生什麼現象?
小知識點:在進行奪標聯合查詢時,儘量給表起別名。這樣可讀性高。

 select e.ename,d.dname from emp e ,dept d;

±-------±------------+
| ename | dname |
±-------±------------+
| SIMITH | ACCOUNTING |
| SIMITH | RESEARCHING |
| SIMITH | SALES |
| SIMITH | OPERATIONS |
| ALLEN | ACCOUNTING |
| ALLEN | RESEARCHING |
| ALLEN | SALES |
| ALLEN | OPERATIONS |

56 rows in set (0.00 sec)

結論:若兩張表進行連接查詢的時候,沒有任何條件限制,最終查詢結果總數總是兩張表記錄條數乘積,這種現象被稱爲笛卡爾積現象。爲了避免笛卡爾積現象的發生,必須在錶鏈接的時候添加限制條件。

4、案例:查詢每一個員工所在部門的名稱,要求最終顯示員工名和對應部門名。

sql92語法:內連接中的等值連接

mysql> select e.ename,d.dname from emp e,dept d where e.deptno=d.deptno;

sql99語法:內連接中的等值連接
sql99語法的優點:表連接獨立出來了,結構清晰,對錶連接不滿意的話,可以再追加where進行過濾。

select e.ename,d.dname from emp e  join dept d on e.deptno=d.deptno; 

±-------±------------+
| ename | dname |
±-------±------------+
| SIMITH | RESEARCHING |
| ALLEN | SALES |
| WARD | SALES |
| JONES | RESEARCHING |
| MARTIN | SALES |
| BLAKE | SALES |
| CLARK | ACCOUNTING |
| SCOTT | RESEARCHING |
| KING | ACCOUNTING |
| TURNER | SALES |
| ADAMS | RESEARCHING |
| JAMES | SALES |
| FORD | RESEARCHING |
| MILLER | ACCOUNTING |
±-------±------------+
14 rows in set (0.01 sec)

5、案例:找出每一個員工對應的工資等級,要求顯示員工名,工資,工資等級等。

sql92語法:內連接中的非等值連接

select e.ename,s.grade from emp e ,salgrade s where e.sal>=s.losal and e.sal<= s.hisal;

sql99語法:內連接中的非等值連接

select e.ename,e.sal, s.grade from emp e inner join salgrade s on e.sal betwee
n s.losal and s.hisal;  //inner可以省略

±-------±--------±------+
| ename | sal | grade |
±-------±--------±------+
| SIMITH | 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 |
±-------±--------±------+

6、案例:找出每一個員工的上級領導,要求顯示員工名以及對應的領導名。

sql92語法:內連接中的自連接

select a.ename empname, b.ename leadername from emp a , emp b where a.mgr=b.empno; 

sql99語法:內連接中的自連接

 select a.ename empname, b.ename leadername from emp a inner join emp b on a.mgr=b.empno;//inner可以省略

±--------±-----------+
| empname | leadername |
±--------±-----------+
| SIMITH | 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 |
±--------±-----------+

7、案例:找出每個員工對應的部門名稱,要求部門名稱全部顯示。

內連接:
A表和B表能夠完全匹配的記錄查詢出來,被稱爲內連接;
外連接:【只掌握SQL99語法】
A表和B表能夠完全匹配的記錄查詢出來之外,將其中一張表的記錄全部無條件能查詢出來,對方表沒有匹配的記錄,會自動模擬出NULL與之匹配,這種查詢被稱爲外連接。
外連接的查詢結果條數>=內連接的查詢結果條數
sql99語法:外連接中的右外連接【右連接】

select e.ename,d.dname from emp e right  outer join dept d on e.deptno=d.deptno;//outer可以省略

sql99語法:外連接中的左外連接【左連接】

select e.ename,d.dname from dept d left  outer join emp e on e.deptno=d.deptno;//outer可以省略

任何一個右外連接都可以寫成左外連接,任何一個左外連接也同樣可以寫成右外連接。
±-------±------------+
| ename | dname |
±-------±------------+
| SIMITH | RESEARCHING |
| ALLEN | SALES |
| WARD | SALES |
| JONES | RESEARCHING |
| MARTIN | SALES |
| BLAKE | SALES |
| CLARK | ACCOUNTING |
| SCOTT | RESEARCHING |
| KING | ACCOUNTING |
| TURNER | SALES |
| ADAMS | RESEARCHING |
| JAMES | SALES |
| FORD | RESEARCHING |
| MILLER | ACCOUNTING |
| NULL | OPERATIONS |
±-------±------------+
爲什麼inner和outer可以省略,加上去有什麼好處?
-可以省略,區分內外連接依靠的不是這些關鍵字,而是看SQL語句中是否存在left/right。若存在,表示一定是一個外連接,其他都是內連接;
-加上去的好處是增強可讀性。

8、案例:找出每一個員工對應的領導名,要求顯示所有的員工。

select a.ename empname,b.ename leadername from emp a left join emp b on a
.mgr=b.empno;

±--------±-----------+
| empname | leadername |
±--------±-----------+
| SIMITH | 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)

9、案例:找出每一個員工對應的部門名稱,以及該員工對應的工資等級。要求顯示員工名、部門名、工資等級。

多張表格進行表連接的語法格式:
select xxx from a join b on 條件 join c on 條件;
原理:a和b表進行表連接之後,a表再和c表進行表連接。

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 |
±-------±------------±------+
| SIMITH | RESEARCHING | 1 |
| ALLEN | SALES | 3 |
| WARD | SALES | 2 |
| JONES | RESEARCHING | 4 |
| MARTIN | SALES | 2 |
| BLAKE | SALES | 4 |
| CLARK | ACCOUNTING | 4 |
| SCOTT | RESEARCHING | 4 |
| KING | ACCOUNTING | 5 |
| TURNER | SALES | 3 |
| ADAMS | RESEARCHING | 1 |
| JAMES | SALES | 1 |
| FORD | RESEARCHING | 4 |
| MILLER | ACCOUNTING | 2 |
±-------±------------±------+

三、子查詢

1、什麼是子查詢?

-select語句嵌套select語句

2、子查詢可以出現在哪裏?

select...(select), from.....(select),where....(select)

3、where 後面使用select子查詢

案例:找出薪水比公司平均薪水高的員工,要求顯示員工名和薪水。
select ename ,sal from emp where sal > avg(sal);
以上語句錯誤,分組函數不能直接使用在where後面。
第一步:找出公司的平均薪資;
select avg(sal) from emp;
第二步:找出薪水大於平均薪水的員工信息

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 |
±------±--------+

4、from後面使用子查詢【小竅門:將查詢結果當作臨時表】

案例:找出每一個部門的平均薪水,並且要求顯示平均薪水的薪水等級
第一步:找出每個部門的平均薪水
select deptno, avg(sal) as avgsal from emp group by deptno;
±-------±------------+
| deptno | avgsal |
±-------±------------+
| 20 | 2175.000000 |
| 30 | 1566.666667 |
| 10 | 2916.666667 |
±-------±------------+
第二步:將上面的查詢結果當作臨時表t,t表和salgrade s表進行表連接,條件:t.avgsal between s.losal and s.hisal;

select
t.deptno,t.avgsal,s.grade
from
t
join
salgrade s
on
t.avgsal between s.losal and s.hisal;
將t表換成第一步的執行結果即可。

select   t.avgsal, s.grade  from (select deptno, avg(sal)  as avgsal   from emp group by deptno) t join salgrade s on  t.avgsal between s.losal and s.hisal;

±------------±------+
| avgsal | grade |
±------------±------+
| 2175.000000 | 4 |
| 1566.666667 | 3 |
| 2916.666667 | 4 |
±------------±------+

5、在select後面使用子查詢【瞭解即可】

select e,ename,(select d,dname from dept d where e.deptno=d.deptno) as dname from emp e;

四、union

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章