数据库知识

ORACLE SQL
SQL(structured query language)


data 持久化(保存)


文件
数据库(database)
table
SQL操作table
DDL(data definition language 数据定义语言)
create table 创建表:colmn,structure
colmn(列):colmn name(列名),data type(数据类型),length(长度),constraint(约束)


alter table修改表结构
修改列(add colmn增加列,modify colmn修改列,drop colmn删除列)
drop table 从数据库中删除表




DML(data manipulation language 数据操作语言):row,data
row(行)
insert into tabame 插入一条记录
update tabname 修改一条记录的某列的值
delete from tabname 删除一条记录


TCL(transaction 事务 control language 事务控制语言):ATM(交易)
commit(提交):让dml操作产生的数据入库
rollback(回滚):让dml操作失效


DQL(data query language数据查询语言)
select


DCL(data control langauge 数据控制语言)
usera,userb
usera
grant select on tabname to userb;
revoke
revoke select on tabname from userb;


使用频度高的语句
DQL,DML,TCL


oracle oracle10g mysql
IBM db2
MS  SQL server
.....


DBA(database administrator 数据库管理员)
install RDBMS(relationship database management system 关系型(二维表:列,行)数据库管理系统)--> create Database(open)-->create user-->(跟数据库建连接(登录,身份认证)-->SQL(DDL DML...),程序员的操作)


solaris
oracle server oracle数据库服务器
oracle for solaris
sqlplus
192.168.0.26  
192.168.0.20
192.168.0.23


远程登录 telnet
Linux终端: telnet 192.168.0.26(登录到26服务器上)
patch补丁 bug
login:openlab
password:open123
sunv210% echo $ORACLE_SID
tarena
sunv210%
%sqlplus 
SQL>
提示符
sunv210% shell里(cmd),os命令
SQL> :where am i
SQL> show user(Who am I)


JDBC TCP/IP
(ip address port(端口 1521) 数据库服务器名字 用户名 密码)


emp employee(员工)
dept department(部门)


create table dept_hiloo
             *
ERROR at line 1:
ORA-00955: name is already used by an existing object


DQL select
emp_jsd1301


newtab不存在
create table newtab(自己起的)
as
select * from oldtab(已经存在的);


newtab表存在,没有数据
insert into newtab
select * from oldtab;


emp,dept select
SQL 4GL 描述语言
select语句
源表 结果集
结果集是表里的部分列:投影操作
结果集是表里的部分行:选择操作
结果集来在多张表的记录的组合:连接操作 


单表操作
多表操作


select语句基本语法:
select colname1,... from tabname;
投影操作用select子句实现


sql语句经sqlplus送给server process(连接建好后标志创建server process进程),对语句进行语法分析,语义分析,产生执行计划并执行,生成结果集, 把结果集传回sqlplus.


select子句
后面跟列名,函数,表达式(数值,字符),运算功能,投影操作
对记录(可能是单列,可能是多列)去重


null的概念
null值,insert into (null)
bonus列不存占空间,未知的
null被看成无穷大
1,(5000+null)*12 = null表达式中有null值,结果为null
空值转换函数
nvl(p1,p2) p1,p2参数
if p1 is null then 
   return p2;
else
   return p1;
end if;


2 如果有多个null,经distinct处理后,保留一个.




字符串的拼接 ||


dual 单列单行用于常量的调用


where子句
where 条件表达式
列名 比较运算符 值
后面有多个条件,用and,or连接


课堂练习
1列出每个员工的名字和他的工资?
select ename,salary from emp_hiloo;
2列出部门表的所有信息?
select * from dept_hiloo;
*表示所有列
3列出每个员工的名字和他的年薪?
select ename,salary*12 
from emp_hiloo;
4列出每个员工的名字和他一年的总收入
select ename,(salary+bonus)*12 ann_sal
from emp_hiloo
ann_sal 列别名


select ename,(salary+bonus)*12 "Ann Sal"
from emp_hiloo
如果列别名中包含空格或希望大小写敏感,用双引号括起来.
(5000+null)*12 = null
(15000+null)*12 = null
(4000+null)*12 = null
select ename,
(salary+nvl(bonus,0))*12 ann_sal
from emp_hiloo;


5
zhangwuji's job is Manager.
liucangsong          Analyst
liyi                 Analyst
guofurong            Programmer
zhangsanfeng         President
yanxiaoliu           Manager
luwushuang           clerk
huangrong            Manager
weixiaobao           salesman
guojing              salesman


' 二义性 表示字符串的定界符,单引号本身
''''表示单引号本身.


select ename||'''s job is '||job
            || '.'  emp
from emp_hiloo


6公司里有哪些职位?
distinct:对记录做去重的,结果集的记录是唯一的.
select distinct job from emp_hiloo


7公司里有哪几类奖金?
select distinct bonus from emp_hiloo;


8各个部门有哪些不同的职位?
select distinct deptno,job 
from emp_hiloo
distinct后面跟多列,多列联合去重.


9哪些员工的工资比5000高?
select ename,salary
from emp_hiloo
where salary > 5000


10哪些员工的工资比5000高,列出名字,年薪
select ename,salary*12 ann_sal
from emp_hiloo
where salary > 5000


11哪些员工的年薪大于60000?列出名字,年薪
select ename,salary*12 ann_sal
from emp_hiloo
where salary*12 > 60000;


select ename,salary*12 
from emp_hiloo
where salary > 5000


select ename,salary*12 ann_sal
from emp_hiloo
where ann_sal > 60000;


ORA-00904: "ANN_SAL": invalid identifier
无效的标识符(没有这个列名)


select语句中各个子句的执行顺序
from --> where --> select


12 zhangwuji的年薪是多少?
select ename,salary*12 ann_sal
from emp_hiloo
where ename = 'zhangwuji'
怎么存怎么写,数据有规则
忽略大小写,upper(p1),返回值大写,lower(p1)小写,initcap(p1)首字符大写


select ename,salary*12 ann_sal
from emp_hiloo
where ename = 'Zhangwuji'
区分大小写,它的编码(ASCII)的值不一样
no rows selected




课外练习
1不知道ename存储的大小写,找出zhangwuji的年薪?
2哪些员工的工资在[5000,10000]之间.
3 哪些员工的奖金是400,500,1000
4 哪些员工的工资不在[5000,10000]之间.
5 哪些员工的奖金不是400,500,1000.


第一天课外练习
1不知道ename存储的大小写,找出zhangwuji的年薪?
select ename,salary*12 ann_sal
from emp_hiloo
where upper(ename) = 'ZHANGWUJI'


zhangwuji-> upper('zhangwuji')->'ZHANGWUJI' = 'ZHANGWUJI'


用函数是不得已而为之
函数目的规范化数据存储,简化select语句的写法.


2哪些员工的工资在[5000,10000]之间.
select ename,salary
from emp_hiloo
where salary >= 5000
and salary <= 10000


3 哪些员工的奖金是400,500,1000
select ename,bonus
from emp_hiloo
where bonus = 400
or    bonus = 500
or    bonus = 1000


4 哪些员工的工资不在[5000,10000]之间.
select ename,salary
from emp_hiloo
where salary < 5000
or salary > 10000


select ename,salary
from emp_hiloo
where salary not between 5000 and 10000


5 哪些员工的奖金不是400,500,1000.
select ename,bonus
from emp_hiloo
where nvl(bonus,0) <> 400
and nvl(bonus,0) <> 500
and nvl(bonus,0) <> 1000


select ename,bonus
from emp_hiloo
where nvl(bonus,0) not in (400,500,1000)


哪些员工的奖金不是400,500,1000,也不能为null?
select ename,bonus
from emp_hiloo
where bonus not in (400,500,1000)


select ename,bonus
from emp_hiloo
where bonus not in (400,500,1000,null)


where子句后面可否跟列别名? 不能


哪些人的奖金是400,500,1000和没有奖金.
select ename, bonus
from emp_hiloo
where bonus in (400,500,1000,null);(错)
select ename, bonus
from emp_hiloo
where bonus in (400,500,1000)
select ename, bonus
from emp_hiloo
where nvl(bonus,0) in (400,500,1000,0)
select ename, bonus
from emp_hiloo
where bonus in (400,500,1000)
or bonus is null


第二天内容
SQL比较运算符
1 >= and <= between ... and,范围,闭区间
where salary between 5000 and 10000


2= or = or in  =any  集合 离散
where bonus in (400,500,1000)
= 单值运算符  in 多值运算符
= -> =any 等于任意一个值


3 like 像...一样 模糊 字符型
通配符  % 表示0过任意多个字符
_ 表示任意一个字符
'S'  like 'S%'1-任意  like 'S_' 条件长度2


DML(记录中包含null值的两种insert方式)
insert into tabname values ('ab',null,...)
insert into tabname(c1,c5) values
('ab',1);


4 判断某列的取值是否为空,用is null,不能用=null


否定形式
= <>
is null is not null
between and not between and
in =any = or = /<> and <> /not in/<>all
用not in比较时,集合中不能包含null值,若包含,no rows selected.
用in比较时,集合中包含null值,是否有null,对结果集没影响.
like not like


函数
nvl upper lower initcap
单行函数:对于每条记录来说,函数都返回一个值
多行函数(组函数):一组记录,函数返回一个值


单行函数
字符函数
upper lower initcap length substr
数值函数
round 四舍五入
        round(12.345,2)  12.35
round(12.5) 13
round(15.5,-1)  20
trunc 截取,取整
trunc(12.545,2)  12
round(12.5) 12
round(15.5,-1)  10


日期函数
        add_months(sysdate,6)
add_months(sysdate,-6)
        months_between(sysdate,hiredate)
        last_day(sysdate)


一般函数
        nvl()
        coalesce
        decode
转换函数
to_date to_char date varchar2
        to_number to_char number varchar2


select ename,empno,nvl(mgr,'Boss')
from emp_hiloo;                    
ERROR at line 1:
ORA-01722: invalid number


select ename,empno,
       nvl(to_char(mgr),'Boss')
from emp_hiloo;  




字符类型:char,varchar2
dname char(20),可以不跟长度,缺省值1char
ename varchar2(20),必须跟长度, 不跟,报错




select length(dname),dname||'D' 
from dept_hiloo;
select length(ename) ,ename||'D'
from emp_hiloo;


char 按定义长度存储,不足补空格,本身定长
varchar2,按实际长度存,本身变长
char比较,空格不敏感
varchar2比较,空格敏感


select ename from emp_hiloo
where ename = 'zhangwuji';
select ename from emp_hiloo
where ename = 'zhangwuji ';
select dname from dept_hiloo
where dname = 'developer';




日期类型
create table test
(c1 date);
insert into test values ('01-JAN-13');
用7个字节存,世纪,年,月,日,时,分,秒
sysdate系统时间
 alter session set nls_date_format = 'yyyy mm dd hh24:mi:ss';
session,会话
建连接 connect,client端(sqlplus jdbc程序)将sql语句送给server process运行,server process创建一个session,是sql语句的运行环境.


'01-JAN-13' 缺省格式:DD-MON-RR 
格式敏感


隐式数据类型转换(系统转 字符转date)
insert into test values ('01-JAN-13');


insert into test values 
(to_date('01-JAN-13','DD-MON-RR'));


insert into test values ('2013-01-01');


显式数据类型转换(用户调)
insert into test values (
to_date('2013-01-01','yyyy-mm-dd'));
ORA-01861: literal(文字) does not match format string(不匹配格式串 DD-MON-RR)


select c1 from test
select to_char(c1,'yyyy-mm-dd')
from test;


日期表达式
date 加减 number = date
date 减 date = number


组函数
avg 平均值 number
sum 求和 number
count 计数 number 字符 date
max 最大值 number 字符 date
min 最小值 number 字符 date
结论:组函数处理所有的非空值
当所有的值都是空值,count返回0,其他函数返回NULL.
所有的null值分为一组
group by 子句
将记录分成若干个组,
group by 列名


select deptno,round(avg(salary))
from emp_hiloo
group by deptno


课堂练习
1哪些员工名字的第二个字符是h?
select ename from emp_hiloo
where ename like '_h%';


2哪些员工的职位是以J_开始?
SQL> insert into emp_hiloo(empno,ename,job)
  2  values (1111,'abc','J_DBA');
SQL> insert into emp_hiloo(empno,ename,job)
  2  values (2222,'def', 'JOB');
select job from emp_hiloo
where job like 'J_%';
rollback;


通配符带着二义性,缺省当通配符解释.
select job from emp_hiloo
where job like 'J\_%' escape '\' 
'\_'表示下划线本身.


3哪些员工没有奖金?
select ename,bonus from emp_hiloo
where bonus is null;
select ename,bonus from emp_hiloo
where bonus = null;


null = null 不成立


4哪些员工有奖金?
select ename,bonus from emp_hiloo
where bonus is not null;
select ename,bonus from emp_hiloo
where bonus <> NULL


400 <> NULL 不成立
NULL <> NULL 不成立
对于NULL来说,任何值做=和<>的比较,都是不成立的.


to_date,to_char
5 emp(empno,ename,hiredate)
2008 08 08 08:08:08


insert into emp_hiloo(empno,ename,hiredate)
values(1111,'abc',
to_date('2008 08 08 08:08:08',
        'yyyy mm dd hh24:mi:ss'))


select to_char(hiredate,
             'yyyy mm dd hh24:mi:ss')
from emp_hiloo
date:to_date to_char 第二个参数都是格式说明


6找出3月份入职的员工?
select ename,hiredate
from emp_hiloo
where to_char(hiredate,'mm') = '03'


select ename,hiredate
from emp_hiloo
where to_char(hiredate,'mm yyyy dd') 
like '03%'


select ename,hiredate
from emp_hiloo
where hiredate like '%MAR%'


select ename,hiredate from emp_hiloo
where to_char(hiredate,'fmMONTH') = 'MARCH'


select ename,hiredate from emp_hiloo
where rtrim(to_char(hiredate,'MONTH')) = 'MARCH'


'MARCH    'varchar2 'MARCH'


select ename,hiredate from emp_hiloo
where to_char(hiredate,'MONTH') like '%MARCH%'




select ename,hiredate
from emp_hiloo
where to_char(hiredate,'fmmm') = '3'
'03'->fm  = '3' 
fm去掉前导0或空格




select ename,hiredate
from emp_hiloo
where to_char(hiredate,'mm') = 3
'03' = 3 隐式数据类型转换
字符   number  字符向数值转
to_number('03') = 3


SQL> select to_number('a9') from dual;
select to_number('a9') from dual
                 *
ERROR at line 1:
ORA-01722: invalid number


7 十分钟之前,十分之之后
select sysdate-1/144,sysdate+1/144
from dual;


8select ename,salary,bonus,
       coalesce(bonus,salary*0.1,100) new_bonus
from emp_hiloo


if p1 is not null then
   return p1;
elsif p2 is not null then
   return p2;
else
     return p3;
end if;


8 case when
  select ename,deptno,
         case when deptno = 10
              then salary*1.1
              when deptno = 20
              then salary*1.2
         else
              salary
         end new_sal
  from emp_hiloo;


  select ename,deptno,
         case when deptno = 10
              then salary*1.1
              when deptno = 20
              then salary*1.2
         end new_sal
  from emp_hiloo;


9 select ename,deptno,
         decode(deptno,10,salary*1.1,
                       20,salary*1.2,
                       salary) new_sal
  from emp_hiloo;


10 有奖金的平均值,和,个数,最大值,最小值
select avg(bonus),sum(bonus),
       count(bonus),
       max(bonus), min(bonus)
from emp_hiloo


count(*):返回记录数


11所有人的奖金的平均值,和,个数,最大值,最小值
select avg(nvl(bonus,0)),
       sum(bonus)/count(*),
       count(bonus),
       max(bonus), min(nvl(bonus,0))
from emp_hiloo


12 select avg(bonus),sum(bonus),
          count(bonus),
          max(bonus),min(bonus)
   from emp_hiloo
   where bonus is null;


13 select count(distinct bonus) 
   from emp_hiloo;
 select count(distinct nvl(bonus,0)) from emp_hiloo;


14各个部门的平均工资?(emp)


15每种奖金有多少人?
select bonus,count(empno)
from emp_hiloo
group by bonus
防止表中有null记录(所有的列都是null),一列必须满足非空且唯一的约束


























课外练习
1substr(p1,p2,p3) 求子串,p1要处理的串,p2是起始位置(1开始,从左往右数),p3子串的长度 
 显示每个员工名字的最后两个字符?


2工资小于5000的涨10%,
      在[5000,10000]涨5%,
其他人不变


3 每种奖金有多少人?(null,'NO Bonus')


(内容已经讲完,现在留课外练习)


4 10部门的平均工资?(只显示平均工资)
  10部门的平均工资?(显示部门号,平均工资)


5 10部门,30部门的平均工资,显示部门号,平均工资


6估算语句的结果集
select max(deptno),avg(salary)
 from emp_hiloo
 where deptno in (10,30);


select avg(deptno),avg(salary)
 from emp_hiloo
 where deptno in (10,30);


select min(deptno),avg(salary)
 from emp_hiloo
 where deptno in (10,30);




第二天课外练习
1substr(p1,p2,p3) 求子串,p1要处理的串,p2是起始位置(1开始,从左往右数,-1从右往左数),p3子串的长度 
 显示每个员工名字的最后两个字符?
select ename,substr(ename,-2,2)
from emp_hiloo


select ename,
       substr(ename,length(ename)-1,2)
from emp_hiloo;


2工资小于5000的涨10%,
      在[5000,10000]涨5%,
其他人不变
select ename,salary,
       case when salary < 5000
            then salary*1.1
            when salary between 5000
                        and 10000
            then salary*1.05
       else 
            salary
       end new_sal
from emp_hiloo;




3 每种奖金有多少人?(null,'NO Bonus')
select nvl(to_char(bonus,'No Bonus')),
       count(empno)
from emp_hiloo
group by bonus


4 10部门的平均工资?(只显示平均工资)
  select round(avg(salary))
  from emp_hiloo
  where deptno = 10


  10部门的平均工资?(显示部门号,平均工资)
  select deptno,round(avg(salary))
  from emp_hiloo
  where deptno = 10
  group by deptno


 
  select deptno,round(avg(salary))
  from emp_hiloo
  where deptno = 10
ORA-00937: not a single-group group function


select max(deptno),round(avg(salary))
from emp_hiloo
where deptno = 10;
max的替代物:min avg


结论:在没有group by子句的情况下,select语句后面如果有一个组函数,其他的都得是组函数




select deptno,ename,round(avg(salary))
  from emp_hiloo
  where deptno = 10
  group by deptno
ORA-00979: not a GROUP BY expression
结论:在有group by子句的情况下,select语句后面可以跟组函数,组标识


5 10部门,30部门的平均工资,显示部门号,平均工资
select deptno,round(avg(salary))
from emp_hiloo
where deptno in (10,30)
group by deptno


6估算语句的结果集
select max(deptno),avg(salary)
 from emp_hiloo
 where deptno in (10,30);


select avg(deptno),avg(salary)
 from emp_hiloo
 where deptno in (10,30);


select min(deptno),avg(salary)
 from emp_hiloo
 where deptno in (10,30);


第三天内容
select语句的语法顺序
select from where group by


select语句的执行顺序
from where group by select(组信息)


平均工资比5000高的那些部门的人数?
having子句
select deptno,count(empno)
from emp_hiloo
group by deptno
having round(avg(salary)) > 5000


select语句的语法顺序
select from where group by having


select语句的执行顺序
from where group by having select(组信息)


where和having比较
共同点:过滤,都执行在select之前,都不可以跟列别名
不同点:
where过滤的是记录,后面可以跟任意列名,单行函数,不能跟组函数,执行在group by之前
having过滤的是组,后面可以跟组函数,组标识,不能跟任意的列名(除组标识),单行函数,执行在group by之后


order by子句
select语句的语法顺序
select from where group by having 
order by


select语句的执行顺序
from where group by having select(组信息)
order by
order by 列名,列别名,函数,表达式,位置
select ename,salary
from emp_hiloo
order by 2;
列位置指salary,在select子句后面的位置


select 2 from dual;
2是常量


排序:升序(缺省 asc NULL在最后) 降序(desc在最前面)


子查询
在SQL语句中嵌入select语句
create table newtab
as
select * from oldtab;


insert into newtab
select * from oldtab;


select语句中嵌入select语句.




课堂练习
1哪种奖金的人数多于2人?
select bonus,count(empno)
from emp_hiloo
group by bonus
having count(empno) > 2


2 各个部门不同职位的平均工资?
select deptno,job,round(avg(salary))
from emp_hiloo
group by deptno,job


2列出员工的名字,部门号,工资,部门号升序,同一部门按工资降序.
select ename,deptno,salary
from emp_hiloo
order by deptno,salary desc


3 列出员工的名字和年薪,按年薪降序排列
select ename,salary*12 ann_sal
from emp_hiloo
order by salary desc


单列子查询
4哪些员工的工资是最低的.
select ename,salary
from emp_hiloo
where salary = (select min(salary)
                from emp_hiloo)
执行顺序
先执行子查询(只执行一遍),若返回多条记录,去重,拿到该结果执行主查询.主查询的比较运算符的选择由子查询返回的记录数决定.(单值运算符,多值运算符)


5哪些员工的工资比zhangwuji的工资高?
select ename,salary
from emp_hiloo
where salary > 
     ( select salary from emp_hiloo
       where ename = 'zhangwuji');
insert into emp_hiloo(empno,ename,salary)
values (1111,'zhangwuji',6000);
RA-01427: single-row subquery returns more than one row


比所有的zhangwuji的工资都高
select ename,salary
from emp_hiloo
where salary >all 
     ( select salary from emp_hiloo
       where ename = 'zhangwuji');


select ename,salary
from emp_hiloo
where salary >
     ( select max(salary) from emp_hiloo
       where ename = 'zhangwuji');


select ename,salary
from emp_hiloo
where salary >any 
     ( select salary from emp_hiloo
       where ename = 'zhangwuji');


select ename,salary
from emp_hiloo
where salary >
     ( select min(salary) from emp_hiloo
       where ename = 'zhangwuji');


6哪些部门的平均工资比30部门的平均工资高?
select deptno,round(avg(salary))
from emp_hiloo
group by deptno
having round(avg(salary)) >
         (select round(avg(salary))
          from emp_hiloo
          where deptno = 30)


7哪些人是领导?
select ename from emp_hiloo
where empno in 
          (select mgr from emp_hiloo)
select ename from emp_hiloo
where empno in (400,500,1000,2000,null)


8哪些人是员工? 哪些人不是领导?
select ename from emp_hiloo
where empno not in 
          (400,500,1000,2000,null)


select ename from emp_hiloo
where empno not in 
          (select mgr from emp_hiloo)


select ename from emp_hiloo
where empno not in 
          (select nvl(mgr,empno) 
           from emp_hiloo)


select ename from emp_hiloo
where empno not in 
          (select mgr from emp_hiloo
           where mgr is not null)




雇主employor    雇员employee
boss zhangsf树根    除了zhangsf(树干,叶)
where mgr is null   where mgr is not null


领导manager 员工 staff
树根 树干 树叶
mgr                     not mgr


9哪些员工的工资等于本部门的平均工资
多列子查询
select ename,deptno,salary
from emp_hiloo
where (deptno,salary) in
       (select deptno,round(avg(salary))
        from emp_hiloo
        group by deptno);




10 找出每个部门工资做高的员工?
select ename,deptno,salary
from emp_hiloo
where (deptno,salary) in
       (select deptno,max(salary))
        from emp_hiloo
        group by deptno);
非关联子查询:子查询不会引用主表的列
单列
多列
-------------------------


11哪些员工的工资大于本部门的平均工资
关联子查询:
在子查询中引用主表的列
select ename,deptno,salary
from emp_hiloo o
where o.salary > 
         (select round(avg(salary))
          from emp_hiloo i
          where o.deptno = i.deptno)


exists 存在
select ename from emp_hiloo o
where exists
            (select 1 from emp_hiloo i
             where o.empno = i.mgr);


update emp set ename = 'abc'
where ename = 'zhangwuji'


not exists 不存在


exists和not exists
如果找到匹配,立即返回,exists(记录放入结果集),not exists(过滤)
如果找不到匹配(跟所有的都不匹配),exists(过滤),not exists (记录放入结果集)
select deptno,dname,location
from dept_hiloo o
where not exists 
          (select 1 from emp_hiloo i
           where i.deptno = o.deptno)


哪些部门有员工?部门名称,部门位置,部门号
select deptno,dname,location
from dept_hiloo o
where exists 
          (select 1 from emp_hiloo i
           where i.deptno = o.deptno)


select deptno,dname,location
from dept_hiloo 
where deptno in (
          select deptno from emp_hiloo)


哪些人是员工?那些人不是领导?
select ename from emp_hiloo o
where not exists
          (select 1 from emp_hiloo i
           where i.mgr = o.empno)


exists和in解决匹配问题,肯定问题


not exists(跟所有都不匹配)和not in(<>all)解决否定问题.


子查询
非关联子查询(单列和多列)
关联子查询(exists not exists)
多表查询
连接join
cross join(交叉连接)
inner join(内连接)
outer join(外连接)


cross join


select e.ename,e.deptno,
d.deptno,d.location
from emp_hiloo e cross join dept_hiloo d
where e.deptno = d.deptno
结果集=4*10 笛卡尔积


内连接




课外练习
1 zhangwuji的领导是谁?
2 zhangwuji领导谁?
3 哪些人是领导?
4 哪些人是员工?哪些人不是领导?
5 哪些部门有员工?
6 哪些部门没有员工?
7 结果集是什么?为什么?
select ename from emp_hiloo o
where not exists
          (select 1 from emp_hiloo i
           where o.mgr = i.empno)


select ename from emp_hiloo o
where exists
          (select 1 from emp_hiloo i
           where o.mgr = i.empno)



第三天课外练习
1 zhangwuji的领导是谁?
select ename from emp_hiloo
where empno in 
           (select mgr from emp_hiloo
            where ename = 'zhangwuji')


select ename from emp_hiloo o
where exists 
           (select mgr from emp_hiloo i
            where o.empno = i.mgr
            and i.ename = 'zhangwuji')


2 zhangwuji领导谁?
select ename from emp_hiloo
where mgr in 
          (select empno from emp_hiloo
           where ename = 'zhangwuji');
exists
3 哪些人是领导?
4 哪些人是员工?哪些人不是领导?
5 哪些部门有员工?
6 哪些部门没有员工?


7 结果集是什么?为什么?
employor
select ename from emp_hiloo o
where not exists
          (select 1 from emp_hiloo i
           where o.mgr = i.empno)


employee 9
select ename from emp_hiloo o
where exists
          (select 1 from emp_hiloo i
           where o.mgr = i.empno)


inner join(内连接)
列出员工的名字和他的工作地点
select e.ename,d.location
from emp_hiloo e join dept_hiloo d
ORA-00905: missing keyword 缺少关键字


select e.ename,d.location
from emp_hiloo e join dept_hiloo d
on e.deptno = d.deptno
and e.ename = 'zhangwuji'


from (e d) -->on的and 条件(过滤) -->on join(连接)
驱动表 
匹配表
内连接:匹配记录


zhangwuji在哪个地区?


课堂练习
1列出部门名称和职位?
select disitnct dname,job
from emp_hiloo e join dept_hiloo d
on e.deptno = d.deptno


2哪些员工在beijing上班?
select e.ename,d.location
from emp_hiloo e join dept_hiloo d
on e.deptno = d.deptno
and d.location = 'beijing'


3各个部门的平均工资,列出部门名称,地区名称,平均工资?
select d.dname,d.location,
       round(avg(salary)) a_sal
from emp_hiloo e join dept_hiloo d
on e.deptno = d.deptno
group by d.dname,d.location
from(e d) --> join on -->group by -->select
       min    min
select max(d.dname),max(d.location),
       round(avg(salary)) a_sal
from emp_hiloo e join dept_hiloo d
on e.deptno = d.deptno
group by d.deptno


from后面可以跟子查询
select d.dname,d.location,a.a_sal
from dept_hiloo d join
  (select deptno,round(avg(salary) a_sal
   from emp_hiloo 
   group by deptno) a
on d.deptno = a.deptno




哪些员工的工资比本部门的平均工资高?
select e.ename,e.salary,a.a_sal
from emp_hiloo e join
  (select deptno,round(avg(salary)) a_sal
   from emp_hiloo 
   group by deptno) a
on e.deptno = a.deptno
and e.salary > a.a_sal


列出员工名字和他领导的名字


select t1.ename employee,
       t2.ename manager
from emp_hiloo t1 join emp_hiloo t2
on t1.mgr = t2.empno
t1 10条记录 匹配9条记录 匹配不上 1
t2 10条记录 匹配4条记录 匹配不上 10-4




select t1.ename employee,
       decode(t2.ename,t1.ename,'Boss',
                   t2.ename) manager
from emp_hiloo t1 join emp_hiloo t2
on nvl(t1.mgr,t1.empno) = t2.empno


select distinct t1.ename
from emp_hiloo t1 join emp_hiloo t2
on t1.empno = t2.mgr
   
t1.mgr = t2.empno  t2.ename


select ename from emp_hiloo  o
where exists
         (select 1 from emp_hiloo i
          where o.empno = i.mgr)


outer join(外连接)
from t1 left join t2
on t1.c1 = t2.c2
外连接结果集=内连接的结果集+(t1表中匹配不上的记录和t2表的null记录的组合)


from t1 right join t2
on t1.c1 = t2.c2




from t1 full join t2
on t1.c1 = t2.c2


两种方法,内连接nvl(mgr,empno),外连接
列出员工名字和领导名字(包含zhangsanfeng)
select t1.ename employee,
       nvl(t2.ename,'Boss')
from emp_hiloo t1 left join emp_hiloo t2
on t1.mgr = t2.empno
10 = 9 + 1


各个部门的平均工资,显示部门名称,地区,平均工资(包含40部门)


select d.dname,d.location,a.a_sal
from dept_hiloo d left join
  (select deptno,round(avg(salary)) a_sal
   from emp_hiloo
   group by deptno) a
on d.deptno = a.deptno
4 = 3 + 1


from dept_hiloo d left join emp_hiloo e
on d.deptno = a.deptno
11 = 10 + 1


from dept_hiloo d right join emp_hiloo e
on d.deptno = a.deptno
10 = 10 + 0


哪个部门没有员工?
select d.deptno,d.dname,
       e.empno,e.ename,e.bonus
from dept_hiloo d left join
     emp_hiloo e
on d.deptno = e.deptno
where e.empno is null


内连接 匹配
外连接 (匹配+不匹配 某种表的所有记录要在结果集中),不匹配
对匹配表的过滤发生在连接之前用on过滤(on and) 发生在连接之后用where过滤


对驱动表的过滤一定要用where子句


哪个部门没有叫zhangwuji的?


from dept_hiloo d left join
     emp_hiloo e
on d.deptno = e.deptno
and e.ename = 'zhangwuji'
where e.empno is null
from (e d) -->on过滤e-->left join -->where


否定 外连接 + where 匹配表.非空列 is null


哪些人是员工?(哪些人不是领导)


select t1.ename
from emp_hiloo left t1 join 
   emp_hiloo t2
on t1.empno = t2.mgr t1.mgr = t2.empno
where t2.empno is null
15 = 9 + (10 - 4)


内连接
     等值连接
     自连接
     非等值连接
外连接
     等值连接
     自连接
     非等值连接
SQL> create table salgrade_hiloo
  2  (grade number(2),
  3   lowsal number(8,2),
  4   hisal number(8,2))
  5
SQL> select * from salgrade_hiloo;


     GRADE     LOWSAL      HISAL
---------- ---------- ----------
         5          1       4000
         4       4001       6000
         3       6001       8000
         2       8001      10000
         1      10001      99999
         0     100000     200000


insert into salgrade_hiloo values
(5,1,4000);


select e.ename,e.salary,s.grade
from emp_hiloo e join salgrade_hiloo s
on e.salary between s.lowsal and s.hisal
and s.grade in (3,5)


1在Linux上准备好你们的.sql文件
2在solaris下vi test.sql
按aio中的任意一个键,进入编辑模式,鼠标右键paste,按ESC键,敲:wq!按回车
3%sqlplus jsd1301/jsd1301 @test.sql
4出错
4.1 rm test.sql
5回到1步重新开始


课外练习
1 zhangwuji领导谁?
select ename from emp_hiloo
where mgr in 
          (select empno from emp_hiloo
           where ename = 'zhangwuji');
用exists实现 inner join


2 zhangwuji的领导是谁? inner join


3各个部门的平均工资,显示部门名称,地区,平均工资(包含40部门)三种写法


4 各个级别的人数(两种都要)

第四天课外练习
1 zhangwuji领导谁?
select ename from emp_hiloo
where mgr in 
          (select empno from emp_hiloo
           where ename = 'zhangwuji');
用exists实现 inner join
select ename
from emp_hiloo o
where exists
         (select 1 from emp_hiloo i
          where o.mgr = i.empno
          and i.ename = 'zhangwuji')


select t1.ename,t2.ename
from emp_hiloo t1 join emp_hiloo t2
on t1.empno = t2.mgr
and t1.ename = 'zhangwuji'


2 zhangwuji的领导是谁? inner join
select t1.ename,t2.ename
from emp_hiloo t1 join emp_hiloo t2
on t1.empno = t2.mgr
and t2.ename = 'zhangwuji'


3各个部门的平均工资,显示部门名称,地区,平均工资(包含40部门)三种写法
select d.dname,d.location,
       round(avg(salary)) a_sal
from dept_hiloo d left join emp_hiloo e
on d.deptno = e.deptno
group by d.dname,d.location


select max(d.dname),max(d.location),
       round(avg(salary)) a_sal
from dept_hiloo d left join emp_hiloo e
on d.deptno = e.deptno
group by d.deptno


4 各个级别的人数(两种都要)
select s.grade,count(e.empno)
from emp_hiloo e join salgrade_hiloo s
on e.salary between s.lowsal and s.hisal
group by s.grade


select s.grade,count(e.empno)
from emp_hiloo e right join      salgrade_hiloo s
on e.salary between s.lowsal and s.hisal
group by s.grade


第五天内容
分页问题,排序问题
oracle
rownum 伪列
select ename,rownum from emp_hiloo
特性:记录编号必须从1开始


找出第一条记录
找出第二条记录
找出前二条记录
找出[2,5]条记录


分页问题
第一页:
select ename,salary,rownum
from emp_hiloo
where rownum <= 3;


非一页
select rn,ename,salary
from (
select rownum rn,ename,salary
from emp_hiloo
where rownum <= 6
      )
where rn >= 4


排名问题
select rownum,ename,salary
from emp_hiloo
where rownum <= 3
order by salary desc
 ROWNUM ENAME                    SALARY
------- -------------------- ----------
      1 zhangwuji                 10000
      3 liyi                       9000
      2 liucangsong                8000


select rownum,ename,salary
from(
select ename,salary
from emp_hiloo
order by salary desc
     )
where rownum <= 3


子查询
表连接
集合操作


集合操作
union/union all (并集)
intersect(交集)
minus(差)
连接两条select语句,必须是同构的,列的个数以及数据类型完全一致
union,intersect,minus的结果集都是去重的
union all不去重


select ename,deptno,salary*1.1
from emp_hiloo
where deptno = 10
union all
select ename,deptno,salary*1.2
from emp_hiloo
where deptno = 20
union all
select ename,deptno,salary
from emp_hiloo
where deptno not in (10,20)
改写为case when


列出员工名字和领导名字的对应关系(包含1005) 3种写法
select t1.ename,t2.ename
from emp_hiloo t1 join emp_hiloo t2
on t1.mgr = t2.empno
union all
select ename,'Boss'
from emp_hiloo
where mgr is null


20部门和30部门的共同职位是?
select job from emp_hiloo
where deptno = 20
intersect
select job from emp_hiloo
where deptno = 30


哪个部门没有员工?
select deptno from dept_hiloo
minus
select deptno from emp_hiloo


匹配+不匹配 (外连接+union/union all)
匹配(内连接 in exists intersect)
不匹配(外连接+where 匹配表.非空列 is null not in not exists minus)


DDL(数据类型 约束 constraint)
约束
primary key 主键 pk
foreign key (reference) 外键 fk
not null(非空) nn
unique key  唯一键 uk
check  检查约束  ck


pk目的
不允许表中有null记录和重复记录
pk=nn + uk
列级约束
create table  test
(c1 number(2) constraint test_c1_pk primary key,
 c2 number);


表级约束
create table  test
(c1 number(2),
 c2 number,
 constraint test_c1_pk primary key(c1));




1 m
dept(1) emp(m)
1个部门有多个员工,一个员工属于一个部门
emp(empno,deptno)


m m
student  course  stu_cour
一名学生选多门课程,一门课程被多个学生选


学生选课表 stu_cour
stu_id 
cour_id
pk (stu_id,cour_id)
score
create table stu_cour
(stu_id number(4),
 cour_id number(2),
 score number(3),
 constraint stu_cour_sid_cid_pk
 primary key(stu_id,cour_id)
);
1 1(夫妻)


定义了fk的表称之为子表(child table),被fk列引用的表称之为父表,被fk列引用的列要求是唯一性
1先create parent table,有uk(被引用列),再create child table,定义fk列
2先insert into parent table,再insert into child table
3先delete from child table,再delete from parent table
4先drop child table,再drop parent table


外键约束
保证表的一对多关系
create table child
(c1 number(4) constraint child_c1_pk
    primary key,
 c2 number(2) constraint child_c2_fk
    references parent(c1))
ERROR at line 5:
ORA-00942: table or view does not exist


create table parent
(c1 number(2));
create table child
(c1 number(4) constraint child_c1_pk
    primary key,
 c2 number(2) constraint child_c2_fk
    references parent(c1))
ERROR at line 5:
ORA-02270: no matching unique or primary key for this column-list


alter table parent
add constraint parent_c1_pk 
primary key(c1);
create table child
(c1 number(4) constraint child_c1_pk
    primary key,
 c2 number(2) constraint child_c2_fk
    references parent(c1))
table created


SQL> insert into child values (1,1);
insert into child values (1,1)
ERROR at line 1:
ORA-02291: integrity constraint(违反fk) (HILOO.CHILD_C2_FK) violated - parent key not found


insert into parent values (1);
insert into child values (1,1);


SQL> delete from parent where c1 = 1;
delete from parent where c1 = 1
*
ERROR at line 1:
ORA-02292: integrity constraint (HILOO.CHILD_C2_FK) violated - child record  found


SQL> delete from child where c2 = 1;
SQL> delete from parent where c1 = 1;


drop table parent purge;
ERROR at line 1:
ORA-02449: unique/primary keys in table referenced by foreign keys


drop table parent cascade constraints purge;
alter table child drop constraint child_c2_fk;
drop table parent purge;


cascade constraints 级联约束


级联删除
create table child1
(c1 number(4) constraint child1_c1_pk
    primary key,
 c2 number(2) constraint child1_c2_fk
    references parent(c1)
    on delete cascade)


delete from parent where c1 = 1;(包含了以下两条命令)
delete from child1 where c2 = 1;
delete from parent where c1 = 1;


create table child2
(c1 number(4) constraint child2_c1_pk
    primary key,
 c2 number(2) constraint child2_c2_fk
    references parent(c1)
    on delete set null)
constraint cons_name primary key(c1,c2),


delete from parent where c1 = 1;(包含了以下两条命令)
update child2 set c2 = null
where c2 = 1;
delete from parent where c1 = 1;


fk的表级约束形式
create table child(
c1 nubmer(3) constraint child_c1_pk
             primary key,
c2 number(2),
constraint child_c2_fk foreign key(c2)
           references parent(c1));
student
id pk
name 


course
id pk
name


stu_cour
stu_id fk -> student(id)
cour_id -> course (id)
pk(stu_id,cour_id)
score


not null
强制属性
create table test
(c1 number not null)


unique
保证唯一性
pk,uk比较
共同点:唯一的,被fk所引用
不同点:
pk = uk + nn
uk允许为null,多个null值
create table test
(c1 number constraint test_c1_pk
           primary key,
 c2 number constraint test_c2_uk
           unique,
 c3 number constraint test_c3_uk
           unique)


create table test
(c1 number constraint test_c1_pk
           primary key,
 c2 number ,
 c3 number ,
 constraint test_c3_uk unique(c2,c3))


create table test
(c1 number constraint test_c1_pk
           primary key,
 c2 number not null constraint test_c2_uk
           unique,
 c3 number not null constraint test_c3_uk
           unique)


check约束
create table test(
c1 number constraint test_c1_ck 
          check (c1 > 100)
);


create table test(
c1 number ,
constraint test_c1_ck 
          check (c1 > 100)
);


transaction 
id
balance 余额
4000 a
100  b


create table account
(id  number
 balance number);
insert into account values (1,4000);
insert into account values (2,100);
commit;
update account 
set balance = balance - 3200
where id = 1;
update account
set balance = balance + 3200
where id = 2;
commit;


alter table test drop primary key;


transaction
oltp on-line transaction processing
联机事务处理系统
事务的隔离级别(缺省)
read committed
已经提交了的数据和本session正在修改的数据
如果不commit,操作不生效,其他人看不见.
如果不commit,其他人不能操作同一条记录,会阻塞
如果不commit,ROLLBACK SEGMENT空间不释放
用户 session
jsd1301 102 
student 1 ddl
student 2 表存在 ddl结果,自动commit


1 dml没commit
2 不能看见


DML锁
表级共享锁
行级排他锁
表级共享锁 行级排他锁
s1 ok ok
s2 ok wait
s3 ok ok


DDL DDL排他锁
drop table
ORA-00054: resource busy and acquire with NOWAIT specified


rollback segment(公共空间 dml)
rollback;


课外练习
1 按工资排名的第4到第6名员工找出来.


列出学生名字,课程名字,成绩
每个学生的平均成绩
哪些学生选了所有的课程
哪门课程没人选?


DDL,transaction




















































































































  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值