Oracle day2
20120215
=====================
一.Oracle中的日期处理
select to_char(sysdate, 'yyyy-mm-dd')
from dual;
select ename, hiredate,
round(sysdate - hiredate) days
from emp_ning;
select sysdate - 10 from dual;
select ename, hiredate,
round(months_between(sysdate, hiredate))
as mons
from emp_ning;
--函数的嵌套
f4(f3(f1(f2(p1,p2)), p3), p4)
concat(concat(concat(concat('a','b'),'c'),'d'), 'e')
'a' || 'b' || 'c' || 'd' || 'e'
select 'hello' || 'world' from dual;
--计算三个月以后的时间
select add_months(sysdate, 3)
from dual;
select last_day(sysdate) from dual;
--修改tom的入职时间是12年2月1号
update emp_ning
set hiredate =
to_date('2012/02/01','yyyy/mm/dd')
where ename = 'tom';
--增加一个职员:
--1012, 'jerry', '2012-01-12'
insert into emp_ning
(empno, ename, hiredate)
values(1012, 'jerry',
to_date('2012/01/12','yyyy/mm/dd')
);
to_date('2012-01-12','yyyy-mm-dd')
to_char(sysdate, 'yyyy-mm-dd')
to_char to_number
日期 -------> 字符 --------> 数字
<------ <--------
to_date to_char
to_char to_number
10000 --> $10,000.00 --> 10000
数字 字符 数字
2012-02-01
2012/02/01
04/05/10
二.单行函数计算
nvl(bonus, 0)
upper(job) = 'ANALYST'
round(salary, 2)
to_char(sysdate, 'yyyy/mm/dd')
to_date('2012-01-12','yyyy-mm-dd')
select ename, salary, bonus,
coalesce(bonus, salary * 0.5, 100)
as bo
from emp_ning;
coalesce(list):
返回参数列表中第一个非空值
0-9分
create table ielts_ning(
name char(10),
s1 number(2,1),
s2 number(2,1),
s3 number(2,1),
s4 number(2,1)
);
insert into ielts_ning
values('A', 8, 8, 6, 7);
insert into ielts_ning
values('B', 6, 6, 7, 7);
insert into ielts_ning
values('C', 6, 7, 7, 7);
insert into ielts_ning
values('D', 8, 6.5, 6, 6);
姓名 听力 阅读 写作 口语 总分
name s1 s2 s3 s4
number(2,1)
张三 8 8 6 7 7.25-> 7.5
李四 6 6 7 7 6.5 -> 6.5
6 7 7 7 6.75-> 7
6.125 -> 6
6.625 6.5
[0, 0.25) [0.25, 0.75) [0.75, 1)
0 0.5 1
select name, s1, s2, s3,s4,
(s1+s2+s3+s4)/4 s
from ielts_ning;
7.25
整数位: trunc((s1+s2+s3+s4)/4) -> 7
小数:mod((s1+s2+s3+s4)/4, 1) -> 0.25
select name, s1, s2, s3, s4,
trunc((s1+s2+s3+s4)/4) +
case when mod((s1+s2+s3+s4)/4, 1) < 0.25 then 0
when mod((s1+s2+s3+s4)/4,1)>=0.25 and
mod((s1+s2+s3+s4)/4,1)<0.75
then 0.5
when mod((s1+s2+s3+s4)/4, 1) >= 0.75 then 1
end as total_s
from ielts_ning;
double calculate(double score){
int i = trunc(score);//整数
double j = mod(score, 1); //小数
double result = 0;
if (j < 0.25)
result = i;
else if ( j >= 0.25 && j < 0.75)
result = i + 0.5;
else if ( j >= 0.75)
result = i + 1;
return result;
}
create or replace function calculate_ning(score number)
return number
is
--定义变量
i number; --整数
j number; --小数
result number; --返回结果
begin
--程序体
i := trunc(score); --数据库中赋值:=
j := mod(score, 1);
if j < 0.25 then
result := 0;
elsif j >= 0.25 and j < 0.75 then
result := 0.5;
elsif j >= 0.75 then
result := 1;
end if;
return i + result;
end;
/
Function Created. 表示创建成功
Function Created with Compil...编译错误
SQL>show errors 检查错误信息
修改后, 再次执行, 直到创建成功为止
--函数建立以后,在sql语句中使用
select name, s1, s2, s3, s4, calculate_ning((s1 + s2 + s3 + s4) / 4) from ielts_ning;
--当数据库中提供的函数不够用时,可以创建自己的函数
--和java中定义自己的方法是一样的道理.
nvl length()
upper iterator()
round indexOf()
calcaulate_ning random()
..... code15To18()
第一部分: SQL 语句
第二部分: PL/SQL: 在数据库中编程
包括:funcation 函数
procedure 过程
package 包
trigger 触发器
select ename, job, salary,
case job when 'clerk' then salary * 1.05
when 'Programmer' then salary * 1.1
when 'Analyst' then salary * 1.15
else salary
end as new_sal
from emp_ning;
--用case实现
case when job = 'clerk' then salary * 1.05
when job = 'Programmer' then salary*1.1
when job = 'Analyst' then salary * 1.15
else salary
end
--用decode函数实现
select ename, job, salary,
decode(upper(job), 'CLERK', salary * 1.05,
'PROGRAMMER', salary * 1.1,
'ANALYST', salary * 1.15,
salary) as new_sal
from emp_ning;
三.分组函数计算
count
--求某列的最大值
select max(salary) from emp_ning;
select max(s1) from ielts_ning;
select max(calculate_ning((s1+s2+s3+s4)/4))
from ielts_ning;
select min(salary) from emp_ning
select min(s1) from ielts_ning;
--组函数忽略空值
select avg(nvl(salary, 0))
from emp_ning;
select sum(salary) / count(salary)
from emp_ning;
count / sum / avg / max / min
select deptno, count(*)
from emp_ning
where deptno is not null
group by deptno;
--没有group by短语,语法错误
select deptno, count(*)
from emp_ning
where deptno is not null;
--没有语法错误,信息不全
select count(*)
from emp_ning
where deptno is not null
group by deptno;
--查询各个部门中的最多人数
select max(count(*))
from emp_ning
where deptno is not null
group by deptno;
--哪个部门的人数最多?
select deptno, count(*)
from emp_ning
where deptno is not null
group by deptno
having count(*) = 4;
--查找人数最多的部门号
--10 6
select deptno, count(*)
from emp_ning
where deptno is not null
group by deptno
having count(*) = (
select max(count(*))
from emp_ning
where deptno is not null
group by deptno);
--人数最多的部门的名字和工作地点
select dname, location
from dept_ning
where deptno = 10;
select dname, location
from dept_ning
where deptno = (
select deptno, count(*)
from emp_ning
where deptno is not null
group by deptno
having count(*) = (
select max(count(*))
from emp_ning
where deptno is not null
group by deptno));
select 列, 组函数
from 表
where 条件
group by ...
having...
order by...
--表里没有的数据,需要计算的数据做条件,用having
--表里有的数据, 做条件,用where
--所有的组函数做条件,必须用having
10 10000
20 5000
30 8000
.....
7000
--哪些部门的平均工资比整个机构的平均工资高?
--查询的条件是平均工资,是组函数计算出来的结--果,所以使用having, 而不是where
select deptno, avg(nvl(salary,0))
from emp_ning
group by deptno
having avg(nvl(salary,0)) > (
select avg(nvl(salary,0))
from emp_ning);
--哪个部门的人数超过5个人?
select deptno, count(*)
from emp_ning
group by deptno
having count(*) > 5;
--哪个部门的薪水总和比部门20的薪水总和高?
select deptno, sum(salary)
from emp_ning
group by deptno
having sum(salary) > (
select sum(salary)
from emp_ning
where deptno = 20);
name job salary
a android 8000
b java 5000
c c++ 6000
d java 10000
e android 9000
....
select job, avg(salary)
from mytable
group by job;
四.子查询
select ename from emp_ning
where salary = (select max(salary)
from emp_ning);
--谁的薪水比tom高?
select ename from emp_ning
where salary > (select salary
from emp_ning
where ename = 'tom');
insert into emp_ning(empno, ename, salary)
values(1020, 'tom', 5000);
--再执行
--出错:ORA-01427: 单行子查询,返回了多于一行记录.
--改进:
select ename from emp_ning
where salary > (select salary
from emp_ning
where ename = 'tom'
and deptno = 10);
--子查询结果多于一条记录,
3000
5000
--比两条记录都大: all
--比任何一条大都行: any
select ename ,salary from emp_ning
where salary > all (select salary
from emp_ning
where ename = 'tom');
--谁和tom同部门?
select ename, deptno
from emp_ning
where deptno in (select deptno
from emp_ning
where ename = 'tom')
and ename <> 'tom';
--谁的薪水最高?
select ename from emp_ning
where salary = (select max(salary)
from emp_ning);
--每个部门薪水最高的是谁?
select ename, salary, deptno
from emp_ning
where (deptno, salary)
in(
select deptno, max(salary)
from emp_ning
group by deptno);
--把部门10和20的两个tom薪水都改成10000
update emp_ning
set salary = 10000
where ename = 'tom';
--再查, 查看结果
数据结构 线性表, 树, 图
范式 1NF 2NF 3NF