Oracle 笔记 day02

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

posted on 2012-02-19 13:00  ChenJW  阅读(174)  评论(0编辑  收藏  举报

导航