1、使用邏輯操作符號
問題:查詢工資高於500或者是崗位為manager的雇員,同時還要滿足他們的姓名首字母為大寫的J?
select * from emp where (sal > 500 or job = 'MANAGER') and ename like 'J%';
2、使用order by字句 默認asc
問題:如何按照工資從低到高的順序顯示雇員的信息?
select * from emp order by sal;
問題:按照部門號升序而雇員的工資降序排列
select * from emp order by deptno, sal desc;
3、使用列的別名排序
問題:按年薪排序
select ename, (sal+nvl(comm,0))*12 "年薪" from emp order by "年薪" asc;
備注:別名需要使用“”號圈中,英文不需要“”號
4、聚合函數用法:max,min,avg,sum,count
問題:如何顯示所有員工中最高工資和最低工資?
select max(sal),min(sal) from emp e;
最高工資那個人是誰?
錯誤寫法:select ename, sal from emp where sal=max(sal);
正確寫法:select ename, sal from emp where sal=(select max(sal) from emp);
注意:select ename, max(sal) from emp;這語句執行的時候會報錯,說ora-00937:非單組分組函數。因為max是分組函數,而ename不是分組函數.......
但是select min(sal), max(sal) from emp;這句是可以執行的。因為min和max都是分組函數,就是說:如果列里面有一個分組函數,其它的都必須是分組函數,否則就出錯。這是語法規定的
5、問題:如何顯示所有員工的平均工資和工資總和?
select sum(e.sal), avg(e.sal) from emp e;
查詢最高工資員工的名字,工作崗位
select ename, job, sal from emp e where sal = (select max(sal) from emp);
顯示工資高於平均工資的員工信息
select * from emp e where sal > (select avg(sal) from emp);
6、group by 和 having 子句
group by 用於對查詢的結果分組統計,
having 子句用於限制分組顯示結果。
問題:如何顯示每個部門的平均工資和最高工資?
select avg(sal), max(sal), deptno from emp group by deptno;
(注意:這里暗藏了一點,如果你要分組查詢的話,分組的字段deptno一定要出現在查詢的列表里面,否則會報錯。因為分組的字段都不出現的話,就沒辦法分組了)
問題:顯示每個部門的每種崗位的平均工資和最低工資?
select min(sal), avg(sal), deptno, job from emp group by deptno, job;
問題:顯示平均工資低於2000的部門號和它的平均工資?
select avg(sal), max(sal), deptno from emp group by deptno having avg(sal)< 2000;
7、對數據分組的總結
1 分組函數只能出現在選擇列表、having、order by子句中(不能出現在where中)
2 如果在select語句中同時包含有group by, having, order by 那么它們的順序是group by, having, order by
3 在選擇列中如果有列、表達式和分組函數,那么這些列和表達式必須有一個出現在group by 子句中,否則就會出錯。
如select deptno, avg(sal), max(sal) from emp group by deptno having avg(sal) < 2000;這里deptno就一定要出現在group by中
8、多表查詢
多表查詢是指基於兩個和兩個以上的表或是視圖的查詢。在實際應用中,查詢單個表可能不能滿足你的需求,如顯示sales部門位置和其員工的姓名,這種情況下需要使用到dept表和emp表。
1)、問題:顯示雇員名,雇員工資及所在部門的名字【笛卡爾集】?
SELECT e.ename, e.sal, d.dname FROM emp e, dept d WHERE e.deptno = d.deptno;
規定:多表查詢的條件是至少不能少於表的個數N-1才能排除笛卡爾集(如果有N張表聯合查詢,必須得有N-1個條件,才能避免笛卡爾集合)
2)、問題:顯示部門號為10的部門名、員工名和工資?
SELECT d.dname, e.ename, e.sal FROM emp e, dept d WHERE e.deptno = d.deptno and e.deptno = 10;
3)、問題:顯示各個員工的姓名,工資及工資的級別?
SELECT e.ename, e.sal, s.grade FROM emp e, salgrade s WHERE e.sal BETWEEN s.losal AND s.hisal;
4)、問題:顯示雇員名,雇員工資及所在部門的名字,並按部門排序?
SELECT e.ename, e.sal, d.dname FROM emp e, dept d WHERE e.deptno = d.deptno ORDER by e.deptno;
注意:如果用group by,一定要把e.deptno 放到查詢列里面
5)、自連接
自連接是指在同一張表的連接查詢
問題:顯示某個員工的上級領導的姓名?
比如顯示員工‘FORD’的上級
SELECT worker.ename, boss.ename FROM emp worker, emp boss WHERE worker.mgr = boss.empno AND worker.ename = 'FORD';
6)、子查詢
什么是子查詢?
子查詢是指嵌入在其他sql語句中的select語句,也叫嵌套查詢。
單行子查詢?
單行子查詢是指只返回一行數據的子查詢語句
請思考:顯示與SMITH同部門的所有員工?
思路:
1))、查詢出SMITH的部門號(返回單行結果集)
select deptno from emp WHERE ename = 'SMITH';
2))、顯示
SELECT * FROM emp WHERE deptno = (select deptno from emp WHERE ename = 'SMITH');
數據庫在執行sql是從左到右掃描的,如果有括號的話,括號里面的先被優先執行。
多行子查詢
多行子查詢指返回多行數據的子查詢
請思考:如何查詢和部門10的工作相同的雇員的名字、崗位、工資、部門號
1))、查詢出部門10的所有工作(返回多行結果集)
SELECT DISTINCT job FROM emp WHERE deptno = 10;
2))、顯示
SELECT * FROM emp WHERE job IN (SELECT DISTINCT job FROM emp WHERE deptno = 10);
注意:不能用job=..,因為等號=是一對一的
在多行子查詢中使用all操作符
問題:如何顯示工資比部門30的所有員工的工資高的員工的姓名、工資和部門號?
--方法一
SELECT ename, sal, deptno FROM emp WHERE sal > all(SELECT sal FROM emp WHERE deptno = 30);
--方法二(執行效率最高,使用聚合函數)
SELECT ename, sal, deptno FROM emp WHERE sal > (SELECT max(sal) FROM emp WHERE deptno = 30);
在多行子查詢中使用any操作符
問題:如何顯示工資比部門30的任意一個員工的工資高的員工姓名、工資和部門號?
--方法一
SELECT ename, sal, deptno FROM emp WHERE sal > ANY (SELECT sal FROM emp WHERE deptno = 30);
--方法二(執行效率最高,使用聚合函數)
SELECT ename, sal, deptno FROM emp WHERE sal > (SELECT min(sal) FROM emp WHERE deptno = 30);
多列子查詢
單行子查詢是指子查詢只返回單列、單行數據,多行子查詢是指返回單列多行數據,都是針對單列而言的,而多列子查詢是指查詢返回多個列數據的子查詢語句。
請思考如何查詢與SMITH 的部門和崗位完全相同的所有雇員。
SELECT deptno, job FROM emp WHERE ename = 'SMITH';
SELECT * FROM emp WHERE (deptno, job) = (SELECT deptno, job FROM emp WHERE ename = 'SMITH');
在from子句中使用子查詢
請思考:如何顯示高於自己部門平均工資的員工的信息
思路:
1. 查出各個部門的平均工資和部門號
SELECT deptno, AVG(sal) mysal FROM emp GROUP by deptno;
2. 把上面的查詢結果看做是一張子表
SELECT e.ename, e.deptno, e.sal, ds.mysal
FROM emp e, (SELECT deptno, AVG(sal) mysal FROM emp GROUP by deptno) ds
WHERE e.deptno = ds.deptno AND e.sal > ds.mysal;
小總結:
在這里需要說明的當在from子句中使用子查詢時,該子查詢會被作為一個視圖來對待,因此叫做內嵌視圖,當在from 子句中使用子查詢時,必須給子查詢指定別名。
注意:別名不能用as,如:SELECT e.ename, e.deptno, e.sal, ds.mysal FROM emp e, (SELECT deptno, AVG(sal) mysal FROM emp GROUP by deptno) as ds WHERE e.deptno = ds.deptno AND e.sal > ds.mysal;
在ds前不能加as,否則會報錯(給表取別名的時候,不能加as;但是給列取別名,是可以加as的)
如何衡量一個程序員的水平?
網絡處理能力,數據庫,程序代碼的優化程序的效率要很高
7)、用查詢結果創建新表,這個命令是一種快捷的建表方式
CREATE TABLE mytable (id, name, sal, job, deptno) as SELECT empno, ename, sal, job, deptno FROM emp;
8)、合並查詢
有時在實際應用中,為了合並多個select語句的結果,可以使用集合操作符號union,union all,intersect,minus。
多用於數據量比較大的數據局庫,運行速度快。
1). union
該操作符用於取得兩個結果集的並集。當使用該操作符時,會自動去掉結果集中重復行。
SELECT ename, sal, job FROM emp WHERE sal >2500
UNION
SELECT ename, sal, job FROM emp WHERE job = 'MANAGER';
2).union all
該操作符與union相似,但是它不會取消重復行,而且不會排序。
SELECT ename, sal, job FROM emp WHERE sal >2500
UNION ALL
SELECT ename, sal, job FROM emp WHERE job = 'MANAGER';
該操作符用於取得兩個結果集的並集。當使用該操作符時,不會自動去掉結果集中重復行。
3). intersect
使用該操作符用於取得兩個結果集的交集。
SELECT ename, sal, job FROM emp WHERE sal >2500
INTERSECT
SELECT ename, sal, job FROM emp WHERE job = 'MANAGER';
4). minus
使用該操作符用於取得兩個結果集的差集,他只會顯示存在第一個集合中,而不存在第二個集合中的數據。
SELECT ename, sal, job FROM emp WHERE sal >2500
MINUS
SELECT ename, sal, job FROM emp WHERE job = 'MANAGER';
(MINUS就是減法的意思)
--------------------------------------------------------------------------
Blog:http://www.cnblogs.com/linjiqin/
J2EE、Android、Linux、Oracle QQ交流群:142463980、158560018(滿)
題外話:
本人來自鐵觀音的發源地——泉州安溪,正宗安溪鐵觀音,有需要的友友歡迎加我Q:416501600。
茶葉淘寶店:http://shop61968332.taobao.com/