子查询
子查询在SELECT、UPDATE、DELETE语句内部可以出现SELECT语句。内部的SELECT语句结果可以作为外部语句中条件子句的一部分,也可以作为外部查询的临时表。子查询的类型有:
- 单行子查询:不向外部返回结果,或者只返回一行结果。
- 多行子查询:向外部返回零行、一行或者多行结果。
例:
查询出销售部(SALES)下面的员工姓名,工作,工资。
SQL> SELECT ENAME,JOB,SAL FROM EMP
2 WHERE DEPTNO=(SELECT DEPTNO FROM DEPT WHERE DNAME=‘SALES’)
① 内部查询的结果作为外部查询的条件。
需要注意:
如果内部查询不返回任何记录,则外部条件中字段DEPTNO与NULL比较永远为假,也就是说外部查询不返还任何结果。
在单行子查询中外部查询可以使用=、>、<、>=、<=、<>等比较运算符。
内部查询返回的结果必须与外部查询条件中的字段(DEPTNO)匹配。
如果内部查询返回多行结果则出现错误。
例二:
查询出Emp表中比任意一个销售员(“SALESMAN”)工资低的员工姓名、工作、工资。
SELECT ENAME,JOB,SAL FROM EMP
WHERE SAL<ANY (SELECT SAL FROM EMP WHERE JOB=‘SALESMAN’)
<any:比子查询结果中任意的值都小,也就是说,比子查询结果中最小值还小。
例3:查询出比所有销售员的工资最高的员工姓名,工作,工资。
SELECT ENAME,JOB,SAL FROM EMP
WHERE SAL>ALL (SELECT SAL FROM EMP WHERE JOB=‘SALESMAN’)
'>ALL:比子查询结果中所有值还要大,也就是说,比子查询结果中最大值还要大。
Oracle中的伪列
表中的每一行在数据文件中都有一个物理地址,ROWID伪列返回的就是该行的物理地址。使用ROWID可以快速的定位表中的某一行。ROWID值可以唯一的标识表中的一行。由于ROWID返回的是该行的物理地址,因此使用ROWID可以显示行是如何存储的。
SELECT ROWID,ENAME FROM EMP WHERE SAL>2000; 使用ROWID查询重复数据
使用ROWID查询重复数据
select * from cz a where rowid!=(select max(rowid) from cz where c1=a.c1 and c2=a.c2 and c3=a.c3);
(1).在Oracle中,每一条记录都有一个rowid,rowid在整个数据库中是唯一的,rowid确定了每条记录是在Oracle中的哪一个数据文件、块、行上。
(2).在重复的记录中,可能所有列的内容都相同,但rowid不会相同,所以只要确定出重复记录中那些具有最大rowid的就可以了。
(3)对于a中没有重复的数据rowid只有一个值,所以max(rowid)就是rowid本身,但是对于a中重复的数据rowid会有多个,取最大的一个,这样就去重了。
ROWNUM
在查询的结果集中,ROWNUM为结果集中每一行标识一个行号,第一行返回1,第二行返回2,以此类推。通过ROWNUM伪列可以限制查询结果集中返回的行数。
ROWNUM与ROWID的不同:
ROWID是插入记录时生成,ROWNUM是查询数据时生成。ROWID标识的是行的物理地址。ROWNUM标识的是查询结果中的行的次序
查询出员工表中前5名员工的姓名,工作,工资。
SELECT ROWNUM,ENAME,JOB,SAL FROM EMP WHERE ROWNUM<=5;
查询出工资最高的前5名员工的姓名、工资和工资。
注:“工资最高的前5名”需要先降序排序,再取前5名
SELECT ROWNUM,T.* FROM ①
(SELECT ENAME,JOB,SAL
FROM EMP ORDER BY SAL DESC) T ②
WHERE ROWNUM<=5
查询出表EMP中第5条到第10条之间的记录。
SELECT * FROM
(SELECT ROWNUM R,ENAME,JOB,SAL
FROM EMP WHERE ROWNUM<=10)
WHERE R>5
内部查询中得到ROWNUM 并且用别名R记录,供外层条件③使用
Oracle函数
3. 单行函数:对每一个函数应用在表的记录中时,只能输入一行结果,返回一个结果,比如:MOD(x,y)返回x除以y的余数(x和y可以是两个整数,也可以是表中的整数列)。常用的单行函数有:
字符函数:对字符串操作。
数字函数:对数字进行计算,返回一个数字。
转换函数:可以将一种数据类型转换为另外一种数据类型。
日期函数:对日期和时间进行处理。
4. 聚合函数:聚合函数同时可以对多行数据进行操作,并返回一个结果。比如SUM(x)返回结果集中x列的总合。
字符函数
字符函数接受字符参数,这些参数可以是表中的列,也可以是一个字符串表达式。下表列出了常用的字符函数
说明:
ROUND(X[,Y]),四舍五入。
在缺省y时,默认y=0;比如:ROUND(3.56)=4。
y是正整数,就是四舍五入到小数点后y位。ROUND(5.654,2)=5.65。
y是负整数,四舍五入到小数点左边|y|位。ROUND(351.654,-2)=400。
TRUNC(x[,y]),直接截取,不四舍五入。
在缺省y时,默认y=0;比如:TRUNC (3.56)=3。
y是正整数,就是四舍五入到小数点后y位。TRUNC (5.654,2)=5.65。
y是负整数,四舍五入到小数点左边|y|位。TRUNC (351.654,-2)=300。
日期函数
- ADD_MONTHS(d,n),在某一个日期d上,加上指定的月数n,返回计算后的新日期。d表示日期,n表示要加的月数。
- LAST_DAY(d),返回指定日期当月的最后一天。
转换函数
1.TO_CHAR(d|n[,fmt])
把日期和数字转换为制定格式的字符串。fmt是格式化字符串
SQL> SELECT TO_CHAR(SYSDATE,‘YYYY"年"MM"月"DD"日" HH24:MI:SS’) “date”
FROM DUAL;
date
2009年08月11日 12:06:00
注:在格式化字符串中,使用双引号对非格式化字符进行引用。 - TO_DATE(x [,fmt])
把一个字符串以fmt格式转换为一个日期类型
select TO_DATE(‘2012-02-10’,‘yyyy-mm-dd’) from dual - TO_NUMBER(x)
SQL> SELECT TO_NUMBER(’-12345.67’) “NUM”
FROM DUAL
NUM
-12345.67
其他单行函数
1.NVL(x,value):空值转换函数
如果x为空,返回value,否则返回x。
案例7:对工资是2000元以下的员工,如果没有发奖金,每人奖金100元。
- NVL2(x,value1,value2)
如果x非空,返回value1,否则返回value2。
例:对EMP表中工资为2000元以下的员工,如果没有奖金,则奖金为200元,如果有奖金,则在原来的奖金基础上加100元。
SQL> SELECT ENAME,JOB,SAL,NVL2(COMM,comm+100,200) “comm”
FROM EMP WHERE SAL<2000;
聚合函数:聚合函数同时对一组数据进行操作,返回一行结果,比如计算一组数据的总和,平均值等。
例:求本月所有员工的基本工资总和
SQL> select sum(sal) from emp;
SUM(SAL)
29025
求不同部门的平均工资。
SQL> SELECT DEPTNO,AVG(SAL) FROM EMP GROUP BY DEPTNO;
DEPTNO AVG(SAL)
30 1566.66666
20 2175
10 2916.66666