1,函数
字符函数:
lower 全部转为小写
upper 全部转为大写
initcap 首字母转为大写
——-
concat 连接两个字符串
substr( str, startPosition, count )
从第几个开始,需要截取几个字符,第1个位置是1。
如果第3个参数不指定(即不指定截取几个字符),就表示到最后。
length 求长度
instr 从字符串strA中找出str所在的位置(返回第找到的1个,位置从1开始)
SQL> select instr(‘Hello World!’, ‘llo’) from dual;
INSTR('HELLOWORLD!','LLO')
--------------------------
3
lpad 把字符串str补齐到n个长度,不足就在左边加指定字符c;
如果str.length>n就取str的前n个字符
SQL> select lpad('ith', 5, '**') from dual;
LPAD(
-----
**ith
SQL> select lpad('smith', 3, '*') from dual;
LPA
---
smi
rpad 把字符串str补齐到n个长度,不足就在右边加指定字符c;
如果str.length>n就取str的前n个字符(也是从前面取)
SQL> select rpad('smith', 3, '*') from dual;
RPA
---
smi
trim 从str的两端去掉字符,要是指定的字符时才去掉,使用方式特殊:
例:trim('a' from 'aaHANGZHOUaa') 结果为 'HANGZHOU'
trim('C' from 'aaHANGZHOUaa') 结果为 'aaHANGZHOUaa'
SQL> select trim(' ' from ' HANGZHOU ') from dual;
TRIM('
------
HANGZHOU
SQL> select trim('a' from 'aaa HANGZHOU aa') from dual;
TRIM('A'FR
----------
HANGZHOU
注意:前面只能指定一个字符。
replace 例:replace('aaHANGZHOUaa', 'a', '=') 结果为 '==HANGZHOU=='
数字函数:
round 四舍五入,例 round('45.923', 2) 表示保存两位小数,保留的位数可以指定正、零、负数。
=================================
SQL> select round(32.392, 2) from dual;
ROUND(32.392,2)
---------------
32.39
SQL> select round(32.92, 0) from dual;
ROUND(32.92,0)
--------------
33
SQL> select round(10532.92, -1) from dual;
ROUND(10532.92,-1)
------------------
10530
SQL> select round(10532.92, -2) from dual;
ROUND(10532.92,-2)
------------------
10500
=================================
trunc 截断,舍掉后面的数,保留的位数可以指定正、零、负数。
=================================
SQL> select trunc(32.392, 1) from dual;
TRUNC(32.392,1)
---------------
32.3
SQL> select trunc(10532.92, 0) from dual;
TRUNC(10532.92,0)
-----------------
10532
SQL> select trunc(10532.92, -1) from dual;
TRUNC(10532.92,-1)
------------------
10530
=======================
mod 求余,如 mod(12, 5) 结果为2
SQL> select mod(12, 5) from dual;
MOD(12,5)
----------
2
SQL> select mod(15, 5) from dual;
MOD(15,5)
----------
0
日期函数:
日期可以相减,但不能相加,因为没有意义。
select sysdate-1 昨天, sysdate 今天, sysdate+1 明天 from dual;
昨天 今天 明天
-------------- -------------- --------------
07-3月 -12 08-3月 -12 09-3月 -12
--------------------------------------------
可以用数字除24来向日期中加上或减去小时
SQL> select to_char(sysdate - 1, 'yyyy-mm-dd hh:mi:ss') from dual;
TO_CHAR(SYSDATE-1,'
-------------------
2012-03-07 10:50:09
SQL> select to_char(sysdate - 1/24, 'yyyy-mm-dd hh:mi:ss') from dual;
TO_CHAR(SYSDATE-1/2
-------------------
2012-03-08 09:50:21
SQL> select to_char(sysdate - 1/24/60, 'yyyy-mm-dd hh:mi:ss') from dual;
TO_CHAR(SYSDATE-1/2
-------------------
2012-03-08 10:49:28
======================================
select ename,(sysdate-hiredate) 天,(sysdate-hiredate)/7 星期, (sysdate-hiredate)/30 月,(sysdate-hiredate)/365 年
add_months
========================================
在指定日期上加上n个月时间:
SQL> select add_months(sysdate, 1) from dual;
ADD_MONTHS(SYS
--------------
08-4月 -12
SQL> select add_months(sysdate, -1) from dual;
ADD_MONTHS(SYS
--------------
08-2月 -12
====================================
计算两个日期相差的月数
SQL> select months_between(sysdate, '8-2月-2012') from dual;
MONTHS_BETWEEN(SYSDATE,'8-2月-2012')
------------------------------------
1
SQL> select months_between(sysdate, '9-2月-2012') from dual;
MONTHS_BETWEEN(SYSDATE,'9-2月-2012')
------------------------------------
.982494026
SQL> select months_between(sysdate, '8-4月-2012') from dual;
MONTHS_BETWEEN(SYSDATE,'8-4月-2012')
------------------------------------
-1
====================================
next_day 从某个日期算起,下一个出现该星期几的日期是哪天: select next_day(sysdate,'星期三') from dual;
SQL> select next_day(sysdate, '星期四') from dual;
NEXT_DAY(SYSDA
--------------
15-3月 -12
SQL> select next_day(sysdate, '星期一') from dual;
NEXT_DAY(SYSDA
--------------
12-3月 -12
last_day 当月的最后一天
SQL> select last_day(sysdate) from dual;
LAST_DAY(SYSDA
--------------
31-3月 -12
--------------
SQL> select last_day(sysdate-10) from dual;
LAST_DAY(SYSDA
--------------
29-2月 -12
round
SQL> select round(sysdate, 'month') from dual;
ROUND(SYSDATE,
--------------
01-3月 -12
SQL> select round(sysdate + 20, 'month') from dual;
ROUND(SYSDATE+
--------------
01-4月 -12
trunc
SQL> select trunc(sysdate, 'month') from dual;
TRUNC(SYSDATE,
--------------
01-3月 -12
SQL> select trunc(sysdate+20, 'month') from dual;
TRUNC(SYSDATE+
--------------
01-3月 -12
====================================
找某月第一天(就是m月1日)。
方式一:
SQL> select last_day(add_months(sysdate, -1)) + 1 from dual;
LAST_DAY(ADD_M
--------------
01-3月 -12
方式二:
SQL> select trunc(sysdate, 'month') from dual;
TRUNC(SYSDATE,
--------------
01-3月 -12
=====================================
转换函数:
隐式数据类型转换 与 显式数据类型转换
to_char(date, format)
to_date(string [,format])
to_char(number, format)
to_number(string [,format]) 如: to_number('22') 或 to_number('$22', '$99')
===============================================
SQL> select empno, lower(ename), to_char(sal, 'L999999') from emp;
EMPNO LOWER(ENAM TO_CHAR(SAL,'L999
---------- ---------- -----------------
7369 smith ¥800
7499 allen ¥1600
7521 ward ¥1250
SQL> select empno, lower(ename), to_char(sal, '$999999') from emp;
EMPNO LOWER(ENAM TO_CHAR(
---------- ---------- --------
7369 smith $800
7499 allen $1600
7521 ward $1250
SQL> select empno, lower(ename), to_char(sal, '$00000') from emp;
EMPNO LOWER(ENAM TO_CHAR
---------- ---------- -------
7369 smith $00800
7499 allen $01600
7521 ward $01250
SQL> select empno, lower(ename), to_char(sal, '$999,999.99') from emp;
EMPNO LOWER(ENAM TO_CHAR(SAL,
---------- ---------- ------------
7369 smith $800.00
7499 allen $1,600.00
7521 ward $1,250.00
格式中有其他字符时要使用双引号引起来:
SQL> select to_char(sysdate, 'yyyy"年"mm"月"dd"日" hh"时"mi"分"ss"秒"') from dual;
TO_CHAR(SYSDATE,'YYYY"年"MM
---------------------------
2012年03月08日 09时26分44秒
空值处理函数:
NVL (expr1, expr2)
可以使用的数据类型有日期、字符、数字
NVL2 (expr1, expr2, expr3)
expr1不为NULL,返回expr2;为NULL,就返回expr3( expr1 != null ? expr2 : expr3 )
条件表达式:
用于实现 IF-THEN-ELSE 逻辑。
CASE 表达式:SQL99的语法,比较繁琐。
CASE的使用方式一:
select
empno,
lower(ename),
job,
sal 原来的工资,
( CASE job WHEN 'PRESIDENT' THEN sal + 1000 WHEN 'MANAGER' THEN sal+800 ELSE sal +400 END ) 涨后的工资
from
emp;
CASE的使用方式二:
select
empno,
lower(ename),
job,
sal 原来的工资,
( CASE WHEN job='PRESIDENT' THEN sal + 1000 WHEN job='MANAGER' THEN sal+800 ELSE sal +400 END ) 涨后的工资
from
emp;
DECODE 函数:Oracle自己的语法,类似Java,比较简洁。
decode( 变量, 值1, 则a, 值2, 则b, ... default)
=====================================
select
empno,
lower(ename),
job,
sal 原来的工资,
( DECODE(job, 'PRESIDENT', sal + 1000,
'MANAGER', sal+800,
sal +400)
) 涨后的工资
from
emp;
=====================================
select
empno,
lower(ename),
job,
sal 原来的工资,
( DECODE(job, 'PRESIDENT', sal + 1000,
'MANAGER', sal+800)
) 涨后的工资
from
emp
=====================================
函数嵌套:
嵌套函数的执行顺序是由内到外。
=================================================
2,集合运算
查询属于部门10与部门20的所有员工信息,还可以这样查
select * from emp where deptno=10
加上(这里写集合运算符)
select * from emp where deptno=20;
这就是集合运算。
并集:
UNION 集合a + b的结果,没有重复记录。
UNION ALL 集合a + b的结果,保留所有重复的记录。(用的比较少)
例:查询属于部门10与部门20的所有员工信息。
例:查询工资在500~1500或在1000~2000范围的员工信息(这是两个工资级别)。
交集
Intersect 既属于集合a又属于集合b的记录。
例:查询工资在500~1500又在1000~2000范围的员工信息(这是两个工资级别)。
差集
Minus 集合a - b的结果,即从a中去除所有属于集合b的元素,注意a-b与b-a的结果是不一样的。
例:查询属于500~1500但不属于1000~2000范围的员工信息。
注意:
1,Select语句中参数类型和个数要一致
如果不一致,需要想办法补齐。
例如要补个字符串,不能写个’a’、’b’等,要不影响结果,应补一个null,还要指定类型。
如果是字符串,可以写 to_char(null);
如果要补数字类型,则写 to_number(null)
2,结果集采用第一个select的表头作为表头。
在第一个select上起别名才有用。
在后面的select上起别名就没有用。
3,如果有order by子句
必须放到最后一句查询语句后。
=================================================
3,多表查询
类型:
1. 等值连接
2. 不等值连接
3. 外连接
4. 自连接
等值连接:
例:查询员工信息,要求显示员工的编号,姓名,月薪和部门名称
select e.empno,e.ename,e.sal,d.dname
from emp e,dept d
where e.deptno=d.deptno;
不等值连接:
例:查询员工的工资级别:编号 姓名 月薪和级别
select e.empno,e.ename,e.sal,s.grade
from emp e,salgrade s
where e.sal between s.losal and s.hisal;
过渡用的例子:
按照部门统计员工的人数,要求显示:部门号,部门名称,员工人数
select d.deptno,d.dname,count(e.empno)
from emp e,dept d
where e.deptno=d.deptno
group by d.deptno,d.dname;
结果:
DEPTNO DNAME COUNT(E.EMPNO)
---------- -------------- --------------
10 ACCOUNTING 3
20 RESEARCH 5
30 SALES 6
SQL> select * from dept;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL> select * from emp where deptno=40;
未选定行
期望效果:当连接条件不成立时,仍然希望在结果中包含某些不成立的记录。这就要用到外连接。
外连接:
左外连接:where e.deptno=d.deptno 当连接条件不成立时,等号左边所代表的表的信息仍然显示
右外连接:where e.deptno=d.deptno 当连接条件不成立时,等号右边所代表的表的信息仍然显示
左外连接的写法: where e.deptno=d.deptno(+)
右外连接的写法: where e.deptno(+)=d.deptno
实现上面的效果:
select d.deptno,d.dname,count(e.empno)
from emp e,dept d
where e.deptno(+)=d.deptno
group by d.deptno,d.dname
order by 1;
自连接:利用表的别名,将同一张表视为多张表
例:查询员工信息:xxx的老板是yyy
select e.ename||'的老板是'||b.ename
from emp e, emp b
where e.mgr=b.empno;
使用SQL99标准的连接查询(JOIN..ON..)
内连接
只返回满足连接条件的数据(两边都有的才显示)。
select e., d.
from emp e
inner join dept d
on e.deptno=d.deptno
– 也可以省略inner关键字。
左外连接
左边有值才显示。
select e.*, d.*
from emp e
left outer join dept d
on e.deptno=d.deptno
-- 也可以省略outer关键字
右外连接
右边边有值才显示。
select e.*, d.*
from emp e
right outer join dept d
on e.deptno=d.deptno
-- 也可以省略outer关键字
满外联接
任一边有值就会显示。
select e.*, d.*
from emp e
full outer join dept d
on e.deptno=d.deptno
-- 也可以省略outer关键字
交叉连接:
叉集,就是笛卡尔积
select e.*, d.*
from emp e
cross join dept d
-- 没有连接条件
=================================================
4,处理数据(DML,增删改)
DML,Data Manipulation Language,数据操作语言
插入数据(Insert into):
插入全部列
插入部分列
插入空值
使用 & 变量(创建脚本)
例:
SQL> insert into emp (empno, ename, sal) values (&empno, &ename, &sal)
SQL> insert into emp (empno, ename, sal) values (&empno, '&ename', &sal)
SQL> update emp set ename='&new_name' where empno=&empno
SQL> select empno,ename,&col from emp;
从其它表中拷贝数据
insert into mytable
select mycolums from ...
更新数据(Update)
删除数据(Delete)
删除所有的记录:
Delete
Truncate