1. 程式人生 > >Oracle數據庫查詢簡析

Oracle數據庫查詢簡析

運算符 包括 關心 根據 在操作 和數 字符串截取 date 表示

一、環境準備
   操作系統:CentOS6.8  數據庫:Oracle 11.2.0.4(企業版)
       客戶端工具:Oracle SQL Developer

二、簡單查詢

簡單查詢:查詢一張表的所有數據
語法格式
SELECT [DISTINCT] * 字段 [別名][字段[別名]] FROM 表名稱 [別名];

範例:查詢dept表全備記錄
SELECT * FROM dept;
範例:查詢出每個雇員編號、姓名、基本工資
SELECT empno,ename,sal FROM emp;

範例:查詢每個雇員職位
SELECT job FROM emp;
這個時候發現查詢處理的job內容中出現了重復的數據,可以用DISTINCT 消除掉所有重復內容:

SELECT DISTINCT job FROM emp;
但是,對於重復數據,指的是一行的每個列的記錄都重復,才叫重復數據。
範例:查詢每個雇員姓名、職位
SELECT DISTINCT ename,job FROM emp;

 在進行查詢操作中,可以使用各個屬性的size運算符

範例:顯示每個雇員姓名、職位、基本年薪
SELECT ename,job,sal12 FROM emp;
這個時候顯示一個“SAL
12”,ZHEG 肯定顯示的是查詢列,但是這個列名稱不方便瀏覽,所有此時可以起一個別名。
SELECT ename,job,sal*12 AS income FROM emp;

範例:由於公司福利好,每個月都有200元的飯食補助以及100元車費補助,這個時候年薪:

SELECT ename,job, (sal+200+100)*12 AS income FROM emp;

公司每年的年底多發一個月基本工資
SELECT ename,job, (sal+200+100)*12+sal AS income FROM emp;
範例:觀察“||”的使用
SELECT empno || ‘,‘ || ename FROM emp;
由於“,”屬於原樣輸出字符串,所以必須使用“,”括起來,即:在SQL語句之中,“,”表示的是字符串。
範例:要求限制的數據安裝如下格式顯示:
SELECT ‘雇員編號是:‘ || empno || ‘雇員姓名是:‘ || ename || ‘,基本工資是:‘ || sal || ‘,職位是:‘ || job AS 雇員信息 FROM emp;

三、限定查詢

在之前的簡單查詢之中,是將所有的記錄顯示,但是現在可以對顯示的記錄鏡像過來操作,這就是限定查詢。限定查詢就是在之前語法的基礎

上增加了一個WHERE子句,用戶限定條件,語法如下:
SELECT [DISTINCT] * 字段 [別名][字段[別名]] FROM 表名稱 [別名] [WHERE 條件(S)];
在WHERE自己之後可以增加多個條件,最常見的條件就是基本的關系運算:>、>=、<=、!=(<>)、BETWEEN...AND、
LIKE、IN、IS NULL、,AND、OR、NOT;

1、關系運算
範例:查詢基本工資高於1500的所有雇員信息
SELECT * FROM emp WHERE sal>1500;

範例:查詢所有職位是辦事員的雇員信息:
SELECT FROM emp WHERE job=‘clerk‘;
這個時候沒有返回相應查詢結果,原因是在oracle數據庫中,所有的數據都是區分大小寫的,大面修改如下:
SELECT
FROM emp WHERE job=‘CLERK‘;
以上只是操作一個條件,現在也可以操作多個條件,而這多個條件之間可以使用AND或OR進行連接操作。
範例:查詢工資在1500-3000之間的全部雇員信息
SELECT FROM emp WHERE sal BETWEEN 1000 AND 1500;
等價於
SELECT
FROM emp WHERE sal>=1000 AND sal<=1500;

範例:查詢職位是CLERK,或是SALESMAN的全部信息:
SELECT * FROM emp WHERE job=‘CLERK‘ OR job=‘SALESMAN‘;

範例:查詢職位是CLERK,或是SALESMAN的全部信息,並且要求這些雇員的工作大於1200
SELECT * FROM emp WHERE (job=‘CLERK‘ OR job=‘SALESMAN‘) AND sal>1200;

範例:查詢所有不是職位不是CLERK的信息:
SELECT FROM emp WHERE job<>‘CLERK‘;
等價於
SELECT
FROM emp WHERE job!=‘CLERK‘;
等價於
SELECT * FROM emp WHERE NOT job=‘CLERK‘;

2、範圍判斷 BETWEEN... AND
"BETWEEN 最小值 AND 最大值" ,表示一個範圍間的判斷過程。
範例:查詢基本工資在1500-3000的雇員信息
SELECT * FROM emp WHERE sal BETWEEN 1500 AND 3000;

範例:現在也可以對BETWEEN...AND操作求反
SELECT * FROM emp WHERE NOT sal BETWEEN 1500 AND 3000;

"BETWEEN...AND"操作不僅可以對數字有用,而且對於日期也同樣有用。

範例:要求查詢出在雇員的全部雇員信息
時間範圍:1981_01_01-1981_12-31,使用hiredate字段表示雇傭日期;
hiredate字段上的內容可以使用字符串表示:‘01-JAN-81’-‘31-DEC-81’
SELECT * FROM emp WHERE hiredate BETWEEN ‘01-JAN-81‘ AND ‘03-DEC-81‘; 故障

3、判斷是否為空:IS(NOT)NULL
使用次語法可以判斷某一個字段的內容是否為“null”,但是null和數字0以及空字符是兩個概念。
範例:查詢所有領取獎金的雇員信息:
SELECT FROM emp WHERE comm IS NOT NULL;
等價於
SELECT
FROM emp WHERE NOT comm IS NULL;
範例:查詢所有不領取獎金的雇員
SELECT * FROM emp WHERE comm IS NULL;

4、知道範圍的判斷:IN操作符
IN操作符表示的是指定一個查詢範圍,例如:
範例:查詢雇員編號是7369、7566、7799的雇員信息
如果按照最早做法,使用OR操作:

SELECT FROM emp WHERE empno=7369 OR empno=7566 OR empno=7799;
使用新操作符IN,則代碼簡單:
SELECT
FROM emp WHERE empno IN (7369,7566,7799);
而如果使用NOT IN呢?,則表示不在制定範圍之中。
SELECT FROM emp WHERE empno NOT IN (7369,7566,7799);
註意點:關於NOT IN 問題
如果現在使用IN 操作符,查詢範圍之中存在null,不影響查詢
SELECT
FROM emp WHERE empno IN (7369,7566,7799,null);
如果現在使用NOT IN 操作符,查詢範圍有null,則表示查詢全部數據 難點
SELECT * FROM emp WHERE empno NOT IN (7369,7566,7799,null);

5、模糊查詢:LIKE子句
LIKE 子句的功能提供了模糊查找的操作,例如:某些程序出現的搜索操作,都屬於LIKE子句的實現,但是必須提醒,搜索引擎上的查詢
不是LIKE.
要想使用LIKE子句,必須認識兩個匹配符號:
匹配單個字符: _
匹配任意多個字符:%
範例:要求查詢雇員姓名中以字母A開通的全部雇員信息:
SELECT FROM emp WHERE ename LIKE ‘A%‘;
範例:要求查詢出雇員姓名中第二個字母是A的全部雇員信息:
SELECT
FROM emp WHERE ename LIKE ‘_A%‘;

現在也可以使用NOT 操作,對LIKE 求反

SELECT FROM emp WHERE ename NOT LIKE ‘%A%‘;
另外對於LIKE子句,不一定只能在字符串中使用,可以在任意數據上表示
SELECT
FROM emp WHERE ename LIKE ‘%1%‘ OR hiredate LIKE ‘%1%‘ OR sal LIKE ‘%1%‘;
說明:原因LIKE子句使用
在開發之中,數據庫的模糊查詢肯定使用LIKE子句,但是在使用LIKE子句的時候有一個最多的註意點:如果在模糊查詢上不設置任何的查詢關鍵字的話
(‘%%‘),則表示查詢所有記錄:

3.1 數據的排序
當數據返回查詢結果後,所有數據默認情況是安裝雇員標號排序。我們也可以使用“ORDER BY”子句
指定所需要排序的操作列,語法如下:

SELECT [DISTINCT] * 字段 [別名][字段[別名]]
FROM 表名稱 [別名]
[WHERE 條件(S)];
[ORDER BY 字段 [ASC|DESC] [字段 [ASC|DESC],...]]

“ORDER BY”子句是寫在所有的SQL語句最好的內容,而且對於排序有一下幾點說明:
排序的時候可以指定多個排序的字段;
排序的方式有兩種:
升序(ASC):默認,不寫也是升序;
降序(DESC):需指定,由大到小排序;
範例:查詢所有雇員信息,要求安裝工資排序
SELECT FROM emp ORDER BY sal;
SELECT
FROM emp ORDER BY sal DESC;

範例:查詢所有雇員信息,安裝工作由高到低排序,如果工作相同,則安裝雇傭日期由早到晚排序
此時肯定需要兩個字段排序:工資(DESC),雇傭日期(ASC);
SELECT * FROM emp ORDER BY sal DESC,hiredate ASC;
對於排序操作,一般只在需要的地方使用,而且一定要記住的是,ORDER BY 子句是寫在所有SQL語句最後

3.2單行函數
雖然各個數據庫都是支持SQL語句,但是每一個數據庫也有子句所支持的操作函數,這些就是單行函數,而如果要想進行數據庫開發的話,除了
要會使用SQL外,就是要多學習函數。
單行函數主要分為以下五類:字符函數、數字函數、轉換函數、統一函數;

3.2.1 字符函數
字符函數的功能主要是進行字符串函數的操作,下面給誰幾個字符函數:
UPPER (字符串|列):將輸入的字符串變為大寫返回;
LOWER(字符串|列):將輸入的字符串變為小寫返回;
INITCAP(字符串|列):開頭首字母大寫;
LENGTH(字符串|列):求字符串長度;
REPLACE(字符串|列):進行替換;
SUBSTR(字符串|列),開始點[結束點]:字符串截取;
Oracle 之中有一點比較麻煩,即使要驗證字符串,也必須寫完整的SQL語句,所以在Oracle數據庫中為了用戶的查詢方便
專門提供一個“dual”的虛擬表。
SELECT UPPER(‘hello‘) FROM dual;
大寫轉換作用:在一邊使用之中,用戶輸入數據的時候不會關心數據本身存放是大寫還是小寫
SELECT * FROM emp WHERE ename=‘&str‘;
當然以上的“&”的操作屬於替代變量的內容。
範例:觀察轉小寫的操作,將所有的雇員姓名安裝小寫字母返回
SELECT LOWER(ename) FROM emp;

範例:將每個雇員姓名的開頭首字母大寫
SELECT INITCAP (ename) FROM emp;

範例:查詢出每個雇員姓名的長度
SELECT ename,LENGTH(ename) FROM emp;
範例:查詢姓名長度正好是5的雇員信息
SELECT ename ,LENGTH(ename) FROM emp ename WHERE LENGTH(ename)=5;
範例:使用字母“”替換姓名中的所有字母“A”
SELECT REPLACE(ename,‘A‘,‘
‘) FROM emp;

字符串截取操作有兩種語法;
語法一:SUBSTR(字符串|列,開始點),表示從開始點一直截取到結尾;
SELECT ename,SUBSTR(ename,3) FROM emp;
語法二:SUBSTR(字符串|列,開始點,結束點),表示從開始點截圖到結束點,截取部門內容;
SELECT ename,SUBSTR(ename,0,3) FROM emp;
等價於
SELECT ename,SUBSTR(ename,1,3) FROM emp;
範例:要求截取每個雇員姓名的後三個字母
正常思路:通過長度-2確定開始點
SELECT ename,SUBSTR(ename,LENGTH(ename)-2) FROM emp;
等價於
SELECT ename,SUBSTR(ename,-3) FROM emp;

SUBSTR()也可以設置負數,表示由後指定截取的開始點;

四、多表查詢

之前的查詢都是在一張表裏進行,如果現在使用一張以上的表,就成為多表查詢。
多表查詢語法:

SELECT [DISTICNT] * | 查詢列1 別名1,查詢列2,別名2,...
FROM 表名稱1 別名1,表名稱2,別名2,...
[WHERE 條件(s)]
[ORDER BY 排序字段1 ASC|DESC,排序字段2 ASC|DESC]

範例:下面使用多表查詢,同時查詢emp和dept表
SELECT * FROM emp,dept;
以上查詢使用2個表。
從查詢結果上發現返回的數據是56行,但是emp是14行。

範例:查詢emp表中的記錄數
SELECT COUNT(*) FROM emp;
從查詢結果上看emp中有14條

範例:查詢dept表的記錄數
SELECT COUNT(*) FROM dept;
從查詢結果上看dept中有4條

使用多表查詢會產生笛卡爾乘積。如果表的數據越多,那麽笛卡爾乘積就會越大,如果現在假設
有3張表,每張表有1000條記錄,100010001000

所有多表查詢是不建議過多使用

要想去掉笛卡爾乘積必須使用字段就那些關聯操作。
在emp中表存在一個deptno的字段,在dept表中也存在一個deptno字段,而且emp表中的deptno中的字段
是與dept表中的deptno關聯的,所有deptno屬於關聯字段。

在多表查詢要使用WHERE子句來消除笛卡爾積

範例:修改前面的查詢
SELECT * FROM emp,dept WHERE emp.deptno=dept.deptno;
查詢結果是14行,此時消除了笛卡爾積,但是如果現在名稱過長時,不是很好用,
一般會對表起個別名。

SELECT * FROM emp e, dept d FROM e.deptno=d.deptno;

結果是相同的,所以一般使用多表查詢,最好指定表的別名

範例:要求查詢出雇員的編號、雇員的姓名、部門的編號、部門名稱及部門位置
SELECT e.empno,e.ename,d.deptno,dname,d.loc FROM emp e, dept d WHERE e.deptno=d.deptno;

範例:要求查詢出每個雇員姓名、工作、雇員的直接上級領導的姓名
在emp表中mgr字段表示一個雇員的上級領導的編號,如果要查詢一個雇員的上級領導的姓名,則肯定要將
emp和emp自己進行關聯,這種叫自關聯。

SELECT e.ename,e.job,m.ename FROM emp e, emp m WHERE e.mgr=m.mgr;

範例:要求進一步擴展,將雇員所在部門名稱同時列出
SELECT e.ename,e.job,m.ename ,d.dname FROM emp e, emp m,dept d WHERE e.mgr=m.empno and e.deptno=d.deptno;

思考題:要求查詢每個雇員的姓名、工資、部門名稱、工資在公司的等級(salgrade),及其領導的姓名及工資所在公司的等級。
SELECT e.ename,e.sal,d.dname,s.grade FROM emp e, dept d, salgrade s WHERE e.deptno=d.deptno And e.sal BETWEEN s.losal AND s.hisal;

4.1左連接、右連接

在dept表中存在4條記錄
現在emp表和dept表關聯查詢,查詢一下指定的字段。
SELECT e.empno,e.ename,d.deptno,d.dname FROM emp e, dept d WHERE e.deptno=d.deptno;
此時發現查詢結果中,deptno字段裏沒有出現40的記錄,我們查看在dept表中的部門編號有40,這是為什麽?
因為在雇員表中沒有是40部門的雇員

SELECT e.empno,e.ename,d.deptno,d.dname FROM emp e,dept d WHERE e.deptno(+)=d.deptno;
如果想要40部門顯示出來,在WHERE子句中(+)寫在等會的左邊,發現40部門出現。這個時候是右連接。
因此,
(+)在=右邊是左連接-----連接的時候以左邊為準
(+)在=左邊是右連接-----連接的時候以右邊為準

註意:在開發中左、右連接使用較多,要理解
實際上在之間的查詢中查找雇員姓名及每一位雇員的領導的時候就應該使用左右連接
SELECT e.empno,e.ename,m.empno,m.ename FROM emp e,emp m WHERE e.mgr=m.empno;
一共13行數據,但是emp表中有14條數據
SELECT e.empno,e.ename,m.empno,m.ename FROM emp e,emp m WHERE e.mgr=m.empno(+);

SQL語法

SELECT table1.column,table2.column FROM table1 [CROSS JOIN table2] |
[NATURAL JOIN table2] |
[JOIN table2 USING(column_name)] |
[JOIN table2 ON(table1.column_name=table2.column_name)] |
[LEFT|RIGHT|FULL OUTER JOIN table2 ON(table1.column_name=table2.column_name)];

交叉連接[CROSS JOIN table2]產生笛卡爾積
SELECT FROM emp CROSS JOIN dept;
產生56條記錄,效果和一下查詢一樣
SELECT
FROM emp,dept;

自然連接[CROSS JOIN table2]自動進行關聯字段的匹配
SELECT FROM emp NATURAL JOIN dept;
查詢的結果是14條記錄,自動進行字段的關聯匹配,不用寫WHERE子句的關聯條件,效果和一下查詢結果一樣
SELECT
FROM emp,dept WHERE emp.deptno=dept.deptno;

[JOIN table2 USING dept(column_name)]直接指定關聯的操作列
SELECT * FROM emp JOIN dept USING(deptno);

[JOIN table2 ON(table2.column_name=table2.column_name)]用戶子句變相連接的條件
SELECT * FROM emp JOIN dept ON (emp.deptno=dept.deptno);

[LEFT OUTER JOIN table2 ON(table1.column_name=table2.column_name)]左外連接
[RIGHT OUTER JOIN table2 ON (table1.column_name=table2.column_name)]右外連接
SELECT * FROM emp e RIGHT OUTER JOIN dept d ON (e.deptno=d.deptno);

4.2 組函數和分組統計
組函數也稱為聚合函數
例如:我們把學生可以分為難受和女生兩個組,如果想求每組的人數,平均身高,平均年齡等,
就需要用到分組函數

在SQL中常用的組函數有一下幾個:
COUNT();求全部記錄數
MAX():求出一組中的最大值
MIN():求出一組中的最小值
AVG():求出一組中的平均值
SUM():求和

範例:COUNT()函數
SELECT COUNT(empno) FROM emp;
我們常用COUNT(),最好能夠用字段代替
範例:MAX()、MIN()函數,求最大最小值,一般是針對於數值的字段的,求出所有員工的最高工資,和最低工資和平均工資。
SELECT MAX(sal) 最高工資,MIN(sal) 最低工資,AVG(sal) 平均工資 FROM emp;

範例:求出部門10的所有員工工資的總和
SELECT SUM(sal) 工資總和 FROM emp WHERE deptno=10;

如果如下查詢輸出部門編號和其部門所有員工的工資總和,會產生錯誤。
SELECT deptno,SUM(sal) 工資總和 FROM emp WHERE deptno=10;
發生以上的錯誤信息,是應為這樣的查詢需要進行分組統計
SELECT deptno,SUM(sal) 工資總和 FROM emp WHERE deptno=10 GROUP BY deptno;

分組統計語法格式
SELECT [DISTINCT] * | 查詢列1 列別名1,查詢列2 列別名2,...
FROM 表名稱1 表別名1,表名稱2 表別名2,...
[WHERE 條件]
[ORDER BY 排序字段1,排序字段2 ASC|DESC]
[GROUP BY 分組字段]

範例:求出每個部門的雇員數量
分析:應該按照部門編號deptno進行分組
SELECT deptno,COUNT(empno) FROM emp GROUP BY deptno;

進一步查詢部門編號是10的雇員的總工資,
SELECT deptno,SUM(sal) FROM emp WHERE deptno=10 GROUP BY deptno;

可是如果我們想找出總工資大於9000的部門
SELECT deptno,SUM(sal) FROM emp WHERE SUM(sal)>9000 GROUP BY deptno;
會出現以下錯誤

ORA-00934: 此處不允許使用分組函數

  1. 00000 - "group function is not allowed here"
    Cause:
    Action:
    行 1 列 39 出錯

分組函數只能在分組中使用,不容許在WHERE語句之中出現,那麽如果現在要指定分組的條件,只能通過
HAVING子句
此時的SQL語法格式
SELECT [DISTINCT] * | 查詢列1 列別名1,查詢列2 列別名2,...
FROM 表名稱1 表別名1,表名稱2 表別名2,...
[WHERE 條件]
[ORDER BY 排序字段1,排序字段2 ASC|DESC]
[GROUP BY 分組字段 [HAVING 分組條件]]

SELECT deptno ,SUM(sal) FROM emp GROUP BY deptno HAVING SUM(sal)>9000;

範例:顯示非銷售人員工作名稱以及從事同一工作雇員的月工資的總和,並且要滿足從事同一工作的雇員的月工資合計大於5000,
輸出結果按月工資的合計升序排列

分析:1、顯示非銷售人員條件是:job<>‘SALESMAN‘
SELECT * FROM emp WHERE job<>‘SALESMAN‘;

分析:2、從事同一工作安裝工作分組:GROUP BY job
工作名稱、月工資的總和----分組查詢的是工作名稱和工資合計:job,SUM(sal)
SELECT job,SUM(sal) FROM emp WHERE job<>‘SALESMAN‘ GROUP BY job;
分析:3、工資合計大於5000---分組條件:HAVING SUM(sal)> 5000
SELECT job,SUM(sal) FROM emp WHERE job<>‘SALESMAN‘ GROUP BY job HAVING SUM(sal)>5000;

分析:4、輸出結果按月工資的合計排列----ORDER BY
SELECT job, SUM(sal) FROM emp WHERE job<>‘SALESMAN‘ GROUP BY job HAVING SUM(sal)>5000 ORDER BY SUM(sal) ASC;

因為排序的時候使用SUM(sal)不方便,我們常用列別名解決這個問題
SELECT job, SUM(sal) S FROM emp WHERE job<>‘SALESMAN‘ GROUP BY job HAVING SUM(sal)>5000 ORDER BY S ASC;

小結:
1、如果使用了分組函數,則有兩種可以使用的情況
2、如果不使用應分組的話,則只能單獨使用分組函數

分組的簡單原則:
只要一列存在重復的內容,才可以考慮到分組
分組函數可以嵌套使用,但是在組函數使用的時候,不能再出現分組條件的查詢語句

範例:求出平均工資最高的部門的編號和部門的工資
SELECT deptno,MAX(SUM(sal)) FROM emp GROUP BY deptno;
ORA-00937: 不是單組分組函數

結果出現錯誤,修改代碼,去掉deptno字段的顯示
SELECT MAX(SUM(sal)) FROM emp GROUP BY deptno;

如果需要查詢平均工資最高的部門編號,修改以上的代碼:
SELECT a.d FROM (SELECT deptno d,AVG(sal) av FROM emp GROUP BY deptno) a WHERE a.av>=(SELECT MAX(AVG(sal)) FROM emp GROUP BY deptno);

以上問題的解決采用的子查詢

五、子查詢

子查詢:在一個查詢的內部還包括另外的查詢,則此查詢稱為子查詢

範例:要求查詢比7654工資要高的所有雇員的信息

分析:先查詢出7654的工資
SELECT sal FROM emp WHERE empno=7654;

分析:在此查詢的基礎上再查詢比7654工資高的雇員,只要sal>7654即可
SELECT * FROM emp WHERE sal>(SELECT sal FROM emp WHERE empno=7654);

所有子查詢必須在()中編寫

子查詢在操作中有分為以下三類:
單列查詢:返回的結果是一列的一個內容
單列子查詢:返回多個列,有可能是一個完整的記錄
多行子查詢:返回多條子記錄

範例:要求查詢出工資比7654高,同時與7788從事相同工資的全部雇員信息
根據剛才查詢分析:條件有兩個,一個是sal>7654的工資,同時job=7788的job
SELECT * FROM emp WHERE sal>(SELECT sal FROM emp WHERE empno=7654) AND job=(SELECT job FROM emp WHERE empno=7788);

範例:要求查詢出工資最低的雇員姓名、工作、工資。
分析:工資最低,需要采用到分組函數MIN(sal),首先查詢最低工資
SELECT MIN(sal) FROM emp;
分析:在這個基礎上完善查詢的條件
SELECT ename,job,sal FROM emp WHERE sal=(SELECT MIN(sal) FROM emp);

思考:要求查詢出,部門名稱、部門的員工數,部門的平均工資,部門的最低收入雇員的姓名和最高收入
雇員的姓名。
分析:查詢涉及到兩張表emp和dept

1、如果要想求出每個部門的員工數量及平均工資,則肯定需要使用分組統計,按deptno進行分組
SELECT deptno,COUNT(empno),AVG(sal) FROM emp GROUP BY deptno;

2、但是如果想查詢出部門的名稱,就需要與dept表進行關聯。於是有人寫下一下代碼:
SELECT d.dname,COUNT(e.empno),AVG(sal)FROM emp e, dept d WHERE e.deptno=d.deptno GROUP BY e.deptno;
ORA-00979: 不是 GROUP BY 表達式

可是出現了這樣的錯誤。
在第一步查出部門編號、部門人數、部門平均工資的基礎上,應該把這個作為一個臨時的表與dept表進行關聯。
這樣才能正確的顯示出部門的名稱。
SELECT d.dname,l.c,l.a FROM (SELECT deptno,COUNT(empno) c,AVG(sal) a
FROM emp GROUP BY deptno) l,dept d
WHERE l.deptno=d.deptno;

3、部門的最低收入和最高收入,應該用到MAX()和MIN()函數,依然是根據部門進行分組的,修改以上的代碼,
同時顯示出部門中工資最低和工資最高的員工姓名
SELECT d.dname,l.c,l.a,e.ename,e.sal
FROM (SELECT deptno,COUNT(empno) c,AVG(sal) a,MAX(sal) max,MIN(sal) min
FROM emp
GROUP BY deptno) l,dept d,emp e
WHERE l.deptno=d.deptno AND (e.sal=l.min OR e.sal=l.max);

Oracle數據庫查詢簡析