sql基础知识实例学习
2013-12-09 14:07
399 查看
Oracle 重点
重点:与SELECT 相关的所有
如果你不做DBA,其他知识点暂时理解就够了
/******************************************************/
/******************************************************/
first_name 名
last_name 姓
title 职位
dept_id 部门号
commission_pct 提成(有空值)
select first_name,salary*12 "Ann Sal" from s_emp;
select first_name,salary*12 as "Ann Sal" from s_emp;
空值不等于0
空值不等于空格
算数表达式中为空值,返回空值
select first_name , salary*12*(1+nvl(commission_pct,0)/100) from s_emp;
列出上一次敲入的命令
b) clear scr 或者!clear
清屏
|| 字符串拼接
'' Oracle 中字符和字符串用单引号表示
"" 双引号用于表示别名
select first_name||' '||last_name employee from s_emp;
select first_name||' is int department '||dept_id||'.' from s_emp;
##该公司有哪些职位?
select distinct title from s_emp;
##各个部门有哪些不同的职位?
##distinct 的功能:部门号单独重复,职位单独重复,部门号和职位联合不重复
select distinct dept_id,title from s_emp;
##会报错,因为distinct 只能出现在select 后面,否则会造成逻辑不通
select dept_id,distinct title from s_emp; (X)
##注意:写*会降低效率,公司中一般会禁止写*;
select * from s_emp;
##注意:写SQL,一般公司都有规范
##年薪大于1.2w 的员工的年薪?
##如果salary 字段上建了索引,第一种写法,索引用不上,所以慢
select first_name,salary*12 a_sal
from s_emp
where salary*12 > 12000;
##如果salary 字段上建了索引,第二种写法,效率高些
select first_name,salary*12 a_sal
from s_emp
where salary>1000;
##会报错,where 子句后面不可以跟“列别名”,where 子句执行在select 语句
之前
select first_name,salary*12 a_sal
from s_emp
where a_sal > 12000;
##EX.不会报错,order by 子句可以使用“别名”
select first_name,salary*12 a_sal
from s_emp
order by a_sal;
##列出Carmen 的年薪是多少?
Select first_name,salary*12 a_sal
From s_emp
Where first_name = 'Carmen';
##列出Carmen 的年薪是多少?
select first_name , salary*12 a_sal
from s_emp
where lower(first_name) = 'carmen';
##找出员工工资在1000 与1500 之间
select first_name , salary
from s_emp
where salary>=1000 and salary<=1500;
##between and 就表示了如上含义
select first_name , salary
from s_emp
where salary between 1000 and 1500;
##找出31、41、43 部门员工的姓名和部门号?
select first_name , dept_id
from s_emp
where dept_id=31 or dept_id=41 or dept_id=43;
##简单的表述形式in()
select first_name , dept_id
from s_emp
where dept_id in (31 , 41 , 43);
##另一种表述形式in()相当于=any()
select first_name , dept_id
from s_emp
where dept_id = any(31, 41, 43);
##从连续区间中取值使用Between-And,从离散数值中取值用IN()
(通配符:%表示0 或多个字符;_表示任意单个字符)
##效率高些
where last_name like 'M%'
##结果等同如上
where substr(last_name , 1 , 1) = 'M';
##列出名字的最后两个字母
select first_name , substr(first_name , -2 ,2) from s_emp;
##列出名字的最后两个字母length()函数
select substr(first_name , length(first_name)-1 ,2) from s_emp;
select talble_name from user_tables
where talbe_name like 'S\_%' escape '\';
select first_name , commission_pct from s_emp where commission_pct is null;
NOT IN()
NOT LIKE
IS NOT NULL
##除了31、41、43 部门的部门员工的情况
select first_name , dept_id from s_emp
where dept_id not in(31, 41 , 43);
##等价写法
select first_name , dept_id from s_emp
where dept_id != 31 and dept_id!=41 and dept_id!=43;
##等价写法<>all(31,41,43)
select first_name , dept_id from s_emp
where dept_id <>all (31,41,43);
##任何数据与NULL 比较,都返回false,
##使用not in()时,如果集合中有null 值,则查不出任何记录,对in()没影响
select first_name , dept_id from s_emp
where dept_id not in(31, 41 , 43,null);
## 找出部门号为44,工资大于1000 的员工或者部门号为42 的所有员工?
select last_name , salary , dept_id
from s_emp
where salary >=1000 and dept_id=44 or dept_id=42;
##找出部门号为44 或者42 的,并且工资大于1000 的员工
select last_name , salary , dept_id
from s_emp
where salary >=1000 and (dept_id=44 or dept_id=42);
##如下式相同的结果,系统做了隐式数据类型转换,均为:字符转数值
select first_name , salary from s_emp where salary = 1450;
select first_name , salary from s_emp where salary = '1450';
##相当于
select first_name , salary from s_emp where to_number(salary) = 1450;
##做严格的数据类型匹配相当重要
select first_name , salary from s_emp where salary = 1450;
##输出所有员工的manager_id,如果没有manager_id,则用BOSS 填充
select first_name , nvl(to_char(manager_id) , 'Boss') from s_emp;
/******************************************************/
/******************************************************/
s_emp 员工表
s_dept 部门表
s_region 部门所在地区表
salgrade 工资等级表
emp 员工表
dept 部门表
##查询'Carmen'所在部门的地区?(Canmen 在哪个地区上班?)
##中间表“部门表”
##用几张表就JOIN 几次
##等值连接(内连接的一种):父表的主键==子表的外键
select e.first_name , r.name
from s_emp e
join s_dept d
on e.dept_id = d.id
and e.first_name = 'Carmen'
join s_region r
on d.region_id = r.id;
##亚洲地区有哪些员工?
select e.first_name , r.name
from s_emp e
join s_dept d
on e.dept_id = d.id
join s_region r
on d.region_id = r.id
and r.name = 'Asia';
##列出员工的工资以及对应的工资级别?
select e.ename , e.sal , s.grade
from emp e
join salgrade s
on e.sal between s.losal and s.hisal;
##SMITH 的工资级别?
select e.ename , e.sal , s.grade
from emp e
join salgrade s
on e.sal between s.losal and s.hisal
and e.ename = 'SMITH';
##3, 5 级有哪些员工(哪些员工属于3,5 级)?
select e.ename , e.sal , s.grade
from emp e
join salgrade s
on e.sal between s.losal and s.hisal
and s.grade in(3,5);
##列出员工名和领导名的对应关系
##结果为24 个,少一个manager_id 为空的人(BOSS 丢了)
select e.first_name emplayee , m.first_name manager
from s_emp e
join s_emp m
on e.manager_id = m.id;
##列出哪些人是领导?
select distinct m.first_name
from s_emp e join s_emp m
on m.id = e.manager_id;
## 内连接from t1 join t2 on t1.id = t2.id
##from t1 left outer join t2 on t1.id = t2.id 左边的表做驱动表
##from t1 right outer join t2 on t1.id = t2.id 右边的表做驱动表
##外连接解决的问题:驱动表中的记录在结果集中“一个都不少”
##列出员工名和领导名的对应关系?
select e.first_name employee , nvl(m.first_name,'Boss') manager
from s_emp e
left outer join s_emp m
on e.manager_id = m.id;
##如何写外连接:
##先写出内连接,再确定哪张表当驱动表就可以
##哪个部门没有员工?14 条记录,少1 条
select e.ename , e.deptno
from emp e
join dept d
on e.deptno = d.deptno;
##哪个部门没有员工?15 条记录
select e.ename , e.deptno , d.deptno ,d.dname
from emp e
right join dept d
on e.deptno = d.deptno;
##哪个部门没有员工?15 条记录
select d.deptno ,d.dname , e.ename , e.deptno
from emp e
right join dept d
on e.deptno = d.deptno
where e.empno is null;
##使用外连接解决了两类问题:
1.把所有结果列出到结果集
2.解决否定问题(不是,没有,不包含)
##那些人是员工?(即:那些人不是领导?)
##思路:
##先解决那些人是领导
##能匹配的是领导
##把匹配不上的挑出来
##
select e.first_name , m.first_name
from s_emp e
right join s_emp m
on e.manager_id = m.id;
## 加条件
select e.first_name , m.first_name
from s_emp e
right join s_emp m
on e.manager_id = m.id
where e.id is null;
## 最后列出m.first_name 即可
select m.first_name
from s_emp e
right join s_emp m
on e.manager_id = m.id
where e.id is null;
##
select e.ename , d.dname
from emp e
right join dept d
on e.deptno = d.deptno
and e.ename = 'SMITH';
##驱动表的过滤全部写在where 之后
select e.ename eename , d.dname dename
from emp e
right join dept d
on e.deptno = d.deptno
and e.ename = 'SMITH';
where e.empno is null;
##选择left jon 或者right join 不重要,重要的是选择哪张表做驱动表
##组函数:一堆数据返回的结果
##max()
##avg()
##min()
##avg()
##求所有人的平均工资?
##求所有人的平均提成?
select avg(nvl(commission_pct,0)) from s_emp;
##count()处理的结果如果全为空值,结果返回0
select count(commission_pct) from s_emp where commission_pct is null;
##计算有多少条记录
select count(id) from s_emp;
##求按提成分组,计算人数?
select commission_pct , count(id)
from s_emp
group by commission_pct;
##count()函数中可以加入关键字
select count(title) from s_emp;
##等同于
select count(all title) from s_emp;
##把重复值去掉,再做统计
select count(distinct title) from s_emp;
##列出42 号部门的平均工资
##若有groupby 子句,select 后面可跟group by 后面跟的表达式以及组函
数,其他会报错。
select dept_id , avg(salary)
from s_emp
where dept_id=42
group by dept_id;
##若没有group by 子句,select 后面有一个组函数,其他都必须是组函数
select max(dept_id) , avg(salary)
from s_emp
where dept_id=42;
作业:
insert into salgrade values (6,10000,15000);
##列出每个工资级别有多少员工?
##列出3,5 级有多少员工
##列出每个工资级别有多少员工(若该级别没有员工,也要列出)
/******************************************************/
/******************************************************/
##先执行子查询;子查询只执行一遍
##若子查询返回值为多个,Oracle 会去掉重复值之后,将结果返回主查询
##谁是受老板剥削工资最低的人?
select first_name , salary
from s_emp
where salary = (select min(salary) from s_emp);
##谁跟SMITH 的职位是一样的?
select last_name , title
from s_emp where
title = (select title from s_emp where last_name='Smith')
and last_name != 'Smith';
##如果表中有重复值,如两个'Smith',会报错:
##single-row subquery returns more than one row 单行子查询返回多行
##修改为:
select last_name , title
from s_emp where
title = any (select title from s_emp where last_name='Smith')
and last_name != 'Smith';
##哪些部门的平均工资比32 部门的工资高?
select dept_id , avg(salary)
from s_emp
group by dept_id
having avg(salary) >
(select avg(salary) from s_emp where dept_id = 32);
##那些人是领导?子查询
select first_name
from s_emp
where id in (select manager_id from s_emp);
##那些人是领导?表连接
select distinct m.first_name
from s_emp m
join s_emp e
on e.manager_id = m.id;
##Ben 的领导是谁?子查询
select first_name
from s_emp
where id =
(select manager_id from s_emp where first_name='Ben');
##Ben 领导谁?子查询
select first_name
from s_emp
where manager_id =
(select id from s_emp where first_name='Ben');
##Ben 的领导是谁? 表连接
select m.first_name
from s_emp m
Join s_emp e
on e.first_name = 'Ben' and e.manager_id = m.id;
##Ben 领导谁?表连接
select e.first_name
from s_emp e
join s_emp m
on m.first_name='Ben' and e.manager_id = m.id;
##
select first_name
from s_emp
where id in (select manager_id from s_emp);
##演示代码
##对not in 来说,结果集中如果有null,则整个结果集为null
##结论:对not in 来说,子查询结果集中是不能有null 的
select first_name
from s_emp
where id not in (select manager_id from s_emp);
##查询那些人是员工?
select first_name
from s_emp
where id not in (select manager_id from s_emp where manager_id is not null);
##not in 尽量不用
##哪些部门的员工工资等于本部门员工平均工资?
## 多列
select first_name , dept_id , salary
from s_emp
where (dept_id , salary) in (select dept_id , avg(salary) from s_emp group by dept_id);
##哪些员工的工资比本部门的平均工资高?
select first_name , dept_id , salary
from s_emp outer
where salary > (select avg(salary) from s_emp inner
where outer.dept_id = inner.dept_id);
##找到即返回
##哪些部门有员工?
select dname from dept o
where exists
(select 1 from emp i
where o.deptno = i.deptno);
##那些人是员工?
select first_name from s_emp a
where not exists
(select 1 from s_emp b where a.id =b.manager_id);
总结:
子查询:
非关联in / not in(不建议)
关联exists (比inner join 优势)/ not exist(即outer join + is null)
##列出员工名和领导名?
select first_name employee ,
(select first_name from s_emp i where o.manager_id = i.id) Manager
from s_emp o;
##实现31 部门,32 部门工资分别涨1.1 倍和1.2 倍?
##如果没有else 返回空值
select first_name , salary,
case when dept_id = 31 then salary*1.1
when dept_id = 32 then salary*1.2
else
salary
end ala_sal
from s_emp;
##工资<1000 涨300 块,1000<工资<1500 涨500,其他人不动
select first_name , salary,
case when salary<1000 then salary+300
when salary>1000 and salary<1500 then salary+500
else
salary
end ala_sal
from s_emp;
##decode(参数1,参数2,参数3,参数11,参数12,参数13...)
##表示如果参数1 的值为参数2 则参数3;参数11 的值为参数12 则参数13...
select first_name, salary,
decode(dept_id , 31 , salary*1.1,
32,salary*1.2,
33,salary*1.3,
salary) aft_sal
from s_emp;
select first_name
from s_emp outer
where not exists
(select 1 from s_emp inner where inner.id=outer.manager_id);
##列出所有员工
select first_name
from s_emp outer
where not exists
(select 1 from s_emp inner where outer.id =inner.manager_id);
/******************************************************/
/******************************************************/
1. 约束
not null(非空约束)这是一个列级约束。在建表时,在数据类型的后面加上not
null ,也就是在插入时不允许插入空值。
create table student(id number primary key,name varchar2(32) not null,address
varchar2(32));
primary key (主键约束PK)保证记录的主键唯一且非空,并且每一个表中只能有
一个主键。
foreign key (外建约束FK)被引用的表,叫做parent table(父表),引用方的表叫
做child table(子表),要想创建子表,就要先创建父表,后创建子表,记录的插入
也是如此,先父表后子表,删除记录,要先删除子表记录,后删除父表记录,要修
改记录,如果要修改父表的记录要保证没有被子表引用。要删表时,要先删子表,
后删除父表。
unique key(唯一键),值为唯一的, 如果创建一个uk,系统自动建一个唯一索引
唯一约束,是会忽略空值的,唯一约束,要求插入的记录中的值是为一的。
create table student(id number,name varchar2(32),address varchar2(32),primary key
(id),unique (address));
check 约束
检查约束,可以按照指定条件,检查记录的插入。check 中不能使用尾列,不能使用
函数,不能引用其他字段。
create table sal (a1 number , check(a1>1000));
第一种形式:
create table test(c number primary key );
第二种形式:
create table test(c number , primary key(c) ) ; 表级约束
create table test( c1 number constraints pkc1 primary key ); 此约束有名字: pkc1
carete table parent(c1 number primary key );
create table child (c number primary key , c2 number references parent(c1));
或表级约束定义:
create table child( c number primary key , c2 number , foreign key(c2) references
parent(c1));
create table test(c1 number primary key); 设置主键
create table test(c1 number constraints test_c1 primary key); 定义约束名,默认约束名为
SYS_ 在列后面定义约束称为列级约束
create table test(c1 number primary key(c1)); 所有列定义完后再定义约束称为表级约
束(能定义联合主键)
cretae table test(c1 number,c2 number,priary key(c1,c2)); 定义联合主键
create table child(c1 number primary key); 先要定义父表
create table child(c1 number primary key, c2 number references parent(c1)); 然后定义子
表references parent 定义外键
create table child(c1 number primary key, c2 number references parent(c1) on delete
cascate); on delete cascate 为级联删除
create table child(c1 number primary key, c2 number references parent(c1) on delete set
null); on delete set null 删除后将外键置空
create table child (c1 number primary key, c2 number,foreignkey(c2) references parent(c1));
select first_name , name from s_emp , s_dept;
insert into student value(1,'xxx','xxx');
insert into student(id,name,address) value(1,'xxx','xxx');
注意:有空值的话:
隐式插入
INSERT INTO s_dept (id, name) VALUES (12, 'MIS');
不往想为空的字段中插数据,系统默认为NULL
显示插入
INSERT INTO s_dept VALUES (13, 'Administration', NULL);
select * from s_emp where 1=2; 这样选不出纪录,方便察看表结构
update table 表名set 字段名1=数据1 或表达式1, 字段名2=数据2 或表达式2
[where ....=....];
update shenfenzhen set num=99 where sid=2;
delete from 表名[where ...=...];
用delete 操作删除的记录可以通过rollback 命令回滚操作,会恢复delete 操作删除的
数据。
delete 操作不会释放表所占用的空间,delete 不适合删除记录多的大表。
delete 操作会占用大量的系统资源。
alter table 命令用于修改表的结构(这些命令不会经常用):
增加字段:
alter table 表名add(字段字,字段类型)
删除字段:
alter tbale 表名drop column 字段; (8i 以后才支持)
给列改名:9.2.0 才支持
alter table 表名rename column 旧字段名to 新字段名;
修改字段
alter table 表名modify( 字段,类型)
(此时应注意的问题,更改时要看具体值情况之间的转达换, 改为字符类型时,必
须要为空)
not null 约束是使用alter table .. modify (..,not null),来加上的。
增加约束:
alter table 表名add constraint [约束名] 约束(字段);
只能够增加表级约束。
解除约束:(删除约束)
alter table 表名drop 约束;
(对于主键约束可以直接用此方法,因为一张表中只有一个主键约束名, 注意如果主
键此时还有其它表引用时删除主键时会出错)
alter table father drop primary key cascade;
(如果有子表引用主键时,要用此语法来删除主键,这时子表还存在只是子表中的外键
约束被及联删除了)
alter table 表名drop constraint 约束名;
(怎样取一个约束名:
a、人为的违反约束规定根据错误信息获取!
b、查询视图获取约束名!)
使约束失效或者生效
alter table 表名disable from primary key; (相当于把一个表的主键禁用)
alter table 表名enable primary key;
(enable 时会自动去检查表的记录是不是符合要求,如果有脏数据时必须要先删除脏
数据才可以enable)
更改表名
rename 旧表名to 新表名;
删除表:
trucate table 表名;
(表结构还在,数据全部删除,释放表所占的空间,不支持回退,常用删除大表)
/******************************************************/
/******************************************************/
今天的note 不全,请自己补充
##表大,结果集小
经常出现在where 子句的列
经常用于表连接的列
主键列PK、唯一键列UK
create table test(
create unique index test_c1_idx on test(c1);
create table test_01
as
select * from test;
建索引的目的就是为了加快查询速度。
索引就相于一本的书的目录。索引点系统空间,属于表的附属物。删除一个表时,
相对应的索引也会删除。索引是会进行排序。
##每条记录都有自己的rowid
select rowid,first_name from s_emp;
creating views 视图名;
视图就相当于一条select 语句,定义了一个视图就是定义了一个sql 语句,视图不占空
间,使用view 不会提高性能,但是能简单化sql 语句
(扩展知识: oracle 8i 以后的新视图)
MV 物化视图(占存储空间,把select 结果存在一个空间,会提高查询视图,增强实时
性,但是存在刷新问题,物化视图中的数据存在延迟问题,主要应用在数据仓库中
用要用于聚合表)
使用视图的好处:控制数据访问权限。
如何创建一个视图的例子:
create or replace views test_vi as select * from test1 where c1=1;
or replace 的意义,如果view 存在就覆盖,不存在才创建。
force|no force ,基表存在是使用,不存在是则创建该表。
此时往表test1(base table 基表)中插入数据时:表中没能变化,视图中的数据发生
改变
从视图中插数据时相对应的表会发生改变:
往视图中插数据时,会直接插进基表中,查看视图中的数据时,相当于就是执行创
建时的select 语句。
限制对数据库的访问,简化查询。
简单视图:来自于单表,且select 语句中不能包括函数,能进行DML 操作。
复杂视图:来源于多张表,不能执行DML 操作。
select e.first_name ,e.salary , a.asal
from s_emp e join
(select dept_id , avg(salary) asal from s_emp group by dept_id) a
on e.dept_id = a.dept_id
and e.salary > a.asal;
##出现两条记录
select first_name , rownum from s_emp where rownum <=2;
##无记录,因为rownum 的特点是必须从1 条记录开始找
select first_name , rownum from s_emp where rownum between 4 and 9;
##排名问题:找出前N 条记录
##找出工资最高的前10 个人?
select rownum , first_name , salary
from (select first_name , salary
from s_emp
order by salary desc)
where rownum<=10;
##分页问题
##找出第11 条到第20 条的记录(先找出前20 条记录,再过滤掉前10 条)
##关键点:给rownum 起别名
##越往后走越慢,这种做法效率较低
select rn , first_name , salary
from (select rownum rn , first_name , salary
from s_emp
where rownum <=20)
where rn between 11 and 20;
##去重
select deptno from dept
union
select deptno from emp;
##不去重
select deptno from dept
union all
select deptno from emp;
select deptno from dept
intersect
select deptno from emp;
select deptno from dept
minus
select deptno from emp;
##改表名
rename abc to testabc;
##给列改名
alter table testabc rename column c1 to c10;
/******************************************************/
/******************************************************/
##查询本用户下所拥有的所有表的表名
select table_name from user_tables;
a) SQLPLUS 的buffer 中会缓存最后一条sql 语句
i. 可以使用"/"来执行这最后一条命令
ii. 可以使用edit 命令来编辑最后一条sql 语句
iii. L 命令(list)(sqlplus 命令)可以显示buffer 中最后一条命令
b) desc [表名]
##sqlplus 命令,注意他不是sql 语句,用于查看表的结构。descript 的缩写
desc s_emp;
spool a.lst
a) 也就是在文件中写有sql 语句的文件,可以在sqlplus 中运行
b) 引入sql 脚本
i. sqlplus 用户名/密码@sql 脚本
ii. 注意:在用户名密码输入结束后一定要加空格然后再写@sql 脚本
iii. 在脚本中最后一行写上“exit”,则运行完脚本以后,回到shell 上
dual 测试表
select sysdate from dual;
1)字符函数
字符是大小写敏感的
转小写lower(字段名) --- 其中的参数可以是一个字符串常量或是一个字段名
转大写upper(字段名)
首字母大写initcap(字段名)
字符串拼接concat(字段1, 字段2)
截取子串substr(字段名, 起始位置,取字符个数)
dual 表,是专门用于函数测试和运算的,他只有一条记录
字符串拼接concat(...,....)
求指定子串substr(...,起始位置,取字符个数)
可以使用"-"表示从右向左取,取的时候可以从左往友取。
例:select substr(first_name,-2,2) sub from s_emp;(取后两个)
select substr(first_name,2,2) sub from s_emp;(取前两个)
2)数值函数
四舍五入round(数据,保留小数点后几位)
可以用负数表示小数点前,0,表示小数点后第一位,也就是保留个位,-1 表示个
位(保留到十位)。
例:select round(15.36,1) from dual;
截取数字函数trunc(数据,保留的位数(小数点后位数)) 截取个位之后补0
例:select trunc(123.456,1) from dual;
3)日期函数
日期格式,
全日期格式世纪信息,年月日,时分秒。
缺省日期格式,日-月-年dd-mon-rr
修改当前会话的日期格式,会按照指定的格式输出日期
alter session set nls_date_format='yyyy mm dd hh24:mi:ss';
返回当前日期sysdate
例:select sysdate from dual;
select sysdate+1 from dual; 获得明天的日期,加1,单位是天
日期是格式敏感的
求两个日期间相隔了多少个月months_between(date1,date2)
加减指定数量的月份add_months(date,月数),月数可以为负,负值就是减去相应的
月数。
从date 日期开始的第一个星期五next_day(date,FriDay)
返回月末的日期last_day(date)
截取日期trunc(date,'年或月或日或时分秒')
例:select next_day(sysdate,2) from dual;
例:select trunc(add_months(sysdate,1),'month') from dual;
ROUND('25-MAY-95','MONTH') 01-JUN-95
ROUND('25-MAY-95 ','YEAR') 01-JAN-95
TRUNC('25-MAY-95 ','MONTH') 01-MAY-95
TRUNC('25-MAY-95 ','YEAR') 01-JAN-95
练习:
返回下个月的第一天的日期
select round(last_day(sysdate),'MONTH') from dual;
select add_months(trunc(sysdate,'MONTH'),1);
4)不同数据类型间转换函数
将日期转成字符tochar(date,'日期格式')
日期格式要用有效格式,格式大小写敏感'yyyy mm dd hh24:mi:ss',
'year'(全拼的年),'mm'(数字表示的月) 'month'(全拼的月),'day'(星期的全拼),'ddspth'
(日期的全拼) 'yy mm dd'
例:select to_char(sysdate,'yyyy mm dd hh24:mi:ss')from dual;
将字符转换成数字to_number('...')
将数字转字符to_char(number,'fmt') fmt 是数字格式
将字符串转成日期to_date('...','日期格式')
例:select to_char(to_date('2006 11 03','yyyy mm dd'),'dd-month-yy') from dual;
使用序列sequence
drop table xxxbyx_1;
create table xxxbyx_1(
id number primary key,
name varchar2(20)
);
drop sequence xxx_1;
create sequence xxx_1;
insert into xxxbyx_1 values (xxx_1.nextVal , 'aaa');
insert into xxxbyx_1 values (xxx_1.nextVal , 'bbb');
insert into xxxbyx_1 values (xxx_1.nextVal , 'ccc');
select xxx_1.currval from dual;
重点:与SELECT 相关的所有
如果你不做DBA,其他知识点暂时理解就够了
/******************************************************/
Day01
/******************************************************/
1. s_emp、s_dept 表的字段含义
first_name 名
last_name 姓
title 职位
dept_id 部门号
commission_pct 提成(有空值)
2. 列出所有人的年薪
select first_name,salary*12 from s_emp;3. 给列起别名
select first_name,salary*12 Ann_Sal from s_emp;select first_name,salary*12 "Ann Sal" from s_emp;
select first_name,salary*12 as "Ann Sal" from s_emp;
4. 处理空值的函数nvl(p1,p2)
null Oracle 当做无穷大来处理空值不等于0
空值不等于空格
算数表达式中为空值,返回空值
select first_name , salary*12*(1+nvl(commission_pct,0)/100) from s_emp;
5. SQLPLUS 命令:
a) L列出上一次敲入的命令
b) clear scr 或者!clear
清屏
6. 字段(列名)拼接
|| 字符串拼接
'' Oracle 中字符和字符串用单引号表示
"" 双引号用于表示别名
select first_name||' '||last_name employee from s_emp;
select first_name||' is int department '||dept_id||'.' from s_emp;
7. 去除重复值distinct
##该公司有哪些职位?
select distinct title from s_emp;
##各个部门有哪些不同的职位?
##distinct 的功能:部门号单独重复,职位单独重复,部门号和职位联合不重复
select distinct dept_id,title from s_emp;
##会报错,因为distinct 只能出现在select 后面,否则会造成逻辑不通
select dept_id,distinct title from s_emp; (X)
8. 列出表中所有字段
##注意:写*会降低效率,公司中一般会禁止写*;
select * from s_emp;
9. Oracle 中写SQL 大小写区别在功能上无影响,性能上有影响
##注意:写SQL,一般公司都有规范
10. where 控制子句
##年薪大于1.2w 的员工的年薪?
##如果salary 字段上建了索引,第一种写法,索引用不上,所以慢
select first_name,salary*12 a_sal
from s_emp
where salary*12 > 12000;
##如果salary 字段上建了索引,第二种写法,效率高些
select first_name,salary*12 a_sal
from s_emp
where salary>1000;
##会报错,where 子句后面不可以跟“列别名”,where 子句执行在select 语句
之前
select first_name,salary*12 a_sal
from s_emp
where a_sal > 12000;
##EX.不会报错,order by 子句可以使用“别名”
select first_name,salary*12 a_sal
from s_emp
order by a_sal;
11. 注意:单引号中大小写敏感
##列出Carmen 的年薪是多少?
Select first_name,salary*12 a_sal
From s_emp
Where first_name = 'Carmen';
12. 大小写转换函数lower() upper()
##列出Carmen 的年薪是多少?
select first_name , salary*12 a_sal
from s_emp
where lower(first_name) = 'carmen';
13. AND 和between and 连接符
##找出员工工资在1000 与1500 之间
select first_name , salary
from s_emp
where salary>=1000 and salary<=1500;
##between and 就表示了如上含义
select first_name , salary
from s_emp
where salary between 1000 and 1500;
14. OR 连接符IN()表述形式=ANY()
##找出31、41、43 部门员工的姓名和部门号?
select first_name , dept_id
from s_emp
where dept_id=31 or dept_id=41 or dept_id=43;
##简单的表述形式in()
select first_name , dept_id
from s_emp
where dept_id in (31 , 41 , 43);
##另一种表述形式in()相当于=any()
select first_name , dept_id
from s_emp
where dept_id = any(31, 41, 43);
##从连续区间中取值使用Between-And,从离散数值中取值用IN()
15. LIKE 运算符SUBSTR()函数Length()函数
(通配符:%表示0 或多个字符;_表示任意单个字符)
##效率高些
where last_name like 'M%'
##结果等同如上
where substr(last_name , 1 , 1) = 'M';
##列出名字的最后两个字母
select first_name , substr(first_name , -2 ,2) from s_emp;
##列出名字的最后两个字母length()函数
select substr(first_name , length(first_name)-1 ,2) from s_emp;
16. escape 关键字(表示\后边的符号不是通配符)
select talble_name from user_tables
where talbe_name like 'S\_%' escape '\';
17. IS NULL 判断字段是否为空IS NOT NULL
select first_name , commission_pct from s_emp where commission_pct is null;
18. NOT BETWEEN AND
NOT IN()
NOT LIKE
IS NOT NULL
##除了31、41、43 部门的部门员工的情况
select first_name , dept_id from s_emp
where dept_id not in(31, 41 , 43);
##等价写法
select first_name , dept_id from s_emp
where dept_id != 31 and dept_id!=41 and dept_id!=43;
##等价写法<>all(31,41,43)
select first_name , dept_id from s_emp
where dept_id <>all (31,41,43);
##任何数据与NULL 比较,都返回false,
##使用not in()时,如果集合中有null 值,则查不出任何记录,对in()没影响
select first_name , dept_id from s_emp
where dept_id not in(31, 41 , 43,null);
19. 注意下两句SQL 的区别,理解OR 和AND
## 找出部门号为44,工资大于1000 的员工或者部门号为42 的所有员工?
select last_name , salary , dept_id
from s_emp
where salary >=1000 and dept_id=44 or dept_id=42;
##找出部门号为44 或者42 的,并且工资大于1000 的员工
select last_name , salary , dept_id
from s_emp
where salary >=1000 and (dept_id=44 or dept_id=42);
20. 隐式数据类型转换
##如下式相同的结果,系统做了隐式数据类型转换,均为:字符转数值
select first_name , salary from s_emp where salary = 1450;
select first_name , salary from s_emp where salary = '1450';
##相当于
select first_name , salary from s_emp where to_number(salary) = 1450;
##做严格的数据类型匹配相当重要
select first_name , salary from s_emp where salary = 1450;
21. 显式数据类型转换to_char()函数
##输出所有员工的manager_id,如果没有manager_id,则用BOSS 填充
select first_name , nvl(to_char(manager_id) , 'Boss') from s_emp;
/******************************************************/
Day02
/******************************************************/
1. 表和表之间的关系
s_emp 员工表
s_dept 部门表
s_region 部门所在地区表
salgrade 工资等级表
emp 员工表
dept 部门表
2. 等值连接
##查询'Carmen'所在部门的地区?(Canmen 在哪个地区上班?)
##中间表“部门表”
##用几张表就JOIN 几次
##等值连接(内连接的一种):父表的主键==子表的外键
select e.first_name , r.name
from s_emp e
join s_dept d
on e.dept_id = d.id
and e.first_name = 'Carmen'
join s_region r
on d.region_id = r.id;
##亚洲地区有哪些员工?
select e.first_name , r.name
from s_emp e
join s_dept d
on e.dept_id = d.id
join s_region r
on d.region_id = r.id
and r.name = 'Asia';
3. 非等值连接
##列出员工的工资以及对应的工资级别?
select e.ename , e.sal , s.grade
from emp e
join salgrade s
on e.sal between s.losal and s.hisal;
##SMITH 的工资级别?
select e.ename , e.sal , s.grade
from emp e
join salgrade s
on e.sal between s.losal and s.hisal
and e.ename = 'SMITH';
##3, 5 级有哪些员工(哪些员工属于3,5 级)?
select e.ename , e.sal , s.grade
from emp e
join salgrade s
on e.sal between s.losal and s.hisal
and s.grade in(3,5);
4. 自连接
##列出员工名和领导名的对应关系
##结果为24 个,少一个manager_id 为空的人(BOSS 丢了)
select e.first_name emplayee , m.first_name manager
from s_emp e
join s_emp m
on e.manager_id = m.id;
##列出哪些人是领导?
select distinct m.first_name
from s_emp e join s_emp m
on m.id = e.manager_id;
5. outer join 外连接
## 内连接from t1 join t2 on t1.id = t2.id
##from t1 left outer join t2 on t1.id = t2.id 左边的表做驱动表
##from t1 right outer join t2 on t1.id = t2.id 右边的表做驱动表
##外连接解决的问题:驱动表中的记录在结果集中“一个都不少”
##列出员工名和领导名的对应关系?
select e.first_name employee , nvl(m.first_name,'Boss') manager
from s_emp e
left outer join s_emp m
on e.manager_id = m.id;
##如何写外连接:
##先写出内连接,再确定哪张表当驱动表就可以
##哪个部门没有员工?14 条记录,少1 条
select e.ename , e.deptno
from emp e
join dept d
on e.deptno = d.deptno;
##哪个部门没有员工?15 条记录
select e.ename , e.deptno , d.deptno ,d.dname
from emp e
right join dept d
on e.deptno = d.deptno;
##哪个部门没有员工?15 条记录
select d.deptno ,d.dname , e.ename , e.deptno
from emp e
right join dept d
on e.deptno = d.deptno
where e.empno is null;
##使用外连接解决了两类问题:
1.把所有结果列出到结果集
2.解决否定问题(不是,没有,不包含)
##那些人是员工?(即:那些人不是领导?)
##思路:
##先解决那些人是领导
##能匹配的是领导
##把匹配不上的挑出来
##
select e.first_name , m.first_name
from s_emp e
right join s_emp m
on e.manager_id = m.id;
## 加条件
select e.first_name , m.first_name
from s_emp e
right join s_emp m
on e.manager_id = m.id
where e.id is null;
## 最后列出m.first_name 即可
select m.first_name
from s_emp e
right join s_emp m
on e.manager_id = m.id
where e.id is null;
6. And 在外连接之前做过滤,where 在外连接之后做过滤
##
select e.ename , d.dname
from emp e
right join dept d
on e.deptno = d.deptno
and e.ename = 'SMITH';
##驱动表的过滤全部写在where 之后
select e.ename eename , d.dname dename
from emp e
right join dept d
on e.deptno = d.deptno
and e.ename = 'SMITH';
where e.empno is null;
##选择left jon 或者right join 不重要,重要的是选择哪张表做驱动表
7. full out join 用的比较少
8. 组函数
##组函数:一堆数据返回的结果
##max()
##avg()
##min()
##avg()
##求所有人的平均工资?
##求所有人的平均提成?
select avg(nvl(commission_pct,0)) from s_emp;
##count()处理的结果如果全为空值,结果返回0
select count(commission_pct) from s_emp where commission_pct is null;
##计算有多少条记录
select count(id) from s_emp;
##求按提成分组,计算人数?
select commission_pct , count(id)
from s_emp
group by commission_pct;
##count()函数中可以加入关键字
select count(title) from s_emp;
##等同于
select count(all title) from s_emp;
##把重复值去掉,再做统计
select count(distinct title) from s_emp;
##列出42 号部门的平均工资
##若有groupby 子句,select 后面可跟group by 后面跟的表达式以及组函
数,其他会报错。
select dept_id , avg(salary)
from s_emp
where dept_id=42
group by dept_id;
##若没有group by 子句,select 后面有一个组函数,其他都必须是组函数
select max(dept_id) , avg(salary)
from s_emp
where dept_id=42;
作业:
insert into salgrade values (6,10000,15000);
##列出每个工资级别有多少员工?
##列出3,5 级有多少员工
##列出每个工资级别有多少员工(若该级别没有员工,也要列出)
/******************************************************/
Day03
/******************************************************/1. 子查询
##先执行子查询;子查询只执行一遍
##若子查询返回值为多个,Oracle 会去掉重复值之后,将结果返回主查询
##谁是受老板剥削工资最低的人?
select first_name , salary
from s_emp
where salary = (select min(salary) from s_emp);
##谁跟SMITH 的职位是一样的?
select last_name , title
from s_emp where
title = (select title from s_emp where last_name='Smith')
and last_name != 'Smith';
##如果表中有重复值,如两个'Smith',会报错:
##single-row subquery returns more than one row 单行子查询返回多行
##修改为:
select last_name , title
from s_emp where
title = any (select title from s_emp where last_name='Smith')
and last_name != 'Smith';
##哪些部门的平均工资比32 部门的工资高?
select dept_id , avg(salary)
from s_emp
group by dept_id
having avg(salary) >
(select avg(salary) from s_emp where dept_id = 32);
##那些人是领导?子查询
select first_name
from s_emp
where id in (select manager_id from s_emp);
##那些人是领导?表连接
select distinct m.first_name
from s_emp m
join s_emp e
on e.manager_id = m.id;
##Ben 的领导是谁?子查询
select first_name
from s_emp
where id =
(select manager_id from s_emp where first_name='Ben');
##Ben 领导谁?子查询
select first_name
from s_emp
where manager_id =
(select id from s_emp where first_name='Ben');
##Ben 的领导是谁? 表连接
select m.first_name
from s_emp m
Join s_emp e
on e.first_name = 'Ben' and e.manager_id = m.id;
##Ben 领导谁?表连接
select e.first_name
from s_emp e
join s_emp m
on m.first_name='Ben' and e.manager_id = m.id;
##
select first_name
from s_emp
where id in (select manager_id from s_emp);
##演示代码
##对not in 来说,结果集中如果有null,则整个结果集为null
##结论:对not in 来说,子查询结果集中是不能有null 的
select first_name
from s_emp
where id not in (select manager_id from s_emp);
##查询那些人是员工?
select first_name
from s_emp
where id not in (select manager_id from s_emp where manager_id is not null);
##not in 尽量不用
2. 子查询与空值
##哪些部门的员工工资等于本部门员工平均工资?
## 多列
select first_name , dept_id , salary
from s_emp
where (dept_id , salary) in (select dept_id , avg(salary) from s_emp group by dept_id);
3. 关联子查询
##哪些员工的工资比本部门的平均工资高?
select first_name , dept_id , salary
from s_emp outer
where salary > (select avg(salary) from s_emp inner
where outer.dept_id = inner.dept_id);
4. 常用的关联子查询:EXISTS NOT EXISTS
##找到即返回
##哪些部门有员工?
select dname from dept o
where exists
(select 1 from emp i
where o.deptno = i.deptno);
##那些人是员工?
select first_name from s_emp a
where not exists
(select 1 from s_emp b where a.id =b.manager_id);
总结:
子查询:
非关联in / not in(不建议)
关联exists (比inner join 优势)/ not exist(即outer join + is null)
5. IN 和EXISTS 的比较(非关联和关联子查询的比较)
6. 标量子查询
##列出员工名和领导名?
select first_name employee ,
(select first_name from s_emp i where o.manager_id = i.id) Manager
from s_emp o;
7. CASE WHEN 表达式
##实现31 部门,32 部门工资分别涨1.1 倍和1.2 倍?
##如果没有else 返回空值
select first_name , salary,
case when dept_id = 31 then salary*1.1
when dept_id = 32 then salary*1.2
else
salary
end ala_sal
from s_emp;
##工资<1000 涨300 块,1000<工资<1500 涨500,其他人不动
select first_name , salary,
case when salary<1000 then salary+300
when salary>1000 and salary<1500 then salary+500
else
salary
end ala_sal
from s_emp;
8. DECODE 函数(等同于Case when)
##decode(参数1,参数2,参数3,参数11,参数12,参数13...)
##表示如果参数1 的值为参数2 则参数3;参数11 的值为参数12 则参数13...
select first_name, salary,
decode(dept_id , 31 , salary*1.1,
32,salary*1.2,
33,salary*1.3,
salary) aft_sal
from s_emp;
select first_name
from s_emp outer
where not exists
(select 1 from s_emp inner where inner.id=outer.manager_id);
##列出所有员工
select first_name
from s_emp outer
where not exists
(select 1 from s_emp inner where outer.id =inner.manager_id);
/******************************************************/
Day04
/******************************************************/1. 约束
not null(非空约束)这是一个列级约束。在建表时,在数据类型的后面加上notnull ,也就是在插入时不允许插入空值。
create table student(id number primary key,name varchar2(32) not null,address
varchar2(32));
primary key (主键约束PK)保证记录的主键唯一且非空,并且每一个表中只能有
一个主键。
foreign key (外建约束FK)被引用的表,叫做parent table(父表),引用方的表叫
做child table(子表),要想创建子表,就要先创建父表,后创建子表,记录的插入
也是如此,先父表后子表,删除记录,要先删除子表记录,后删除父表记录,要修
改记录,如果要修改父表的记录要保证没有被子表引用。要删表时,要先删子表,
后删除父表。
unique key(唯一键),值为唯一的, 如果创建一个uk,系统自动建一个唯一索引
唯一约束,是会忽略空值的,唯一约束,要求插入的记录中的值是为一的。
create table student(id number,name varchar2(32),address varchar2(32),primary key
(id),unique (address));
check 约束
检查约束,可以按照指定条件,检查记录的插入。check 中不能使用尾列,不能使用
函数,不能引用其他字段。
create table sal (a1 number , check(a1>1000));
2. primary key 约束(主键约束)
第一种形式:
create table test(c number primary key );
第二种形式:
create table test(c number , primary key(c) ) ; 表级约束
create table test( c1 number constraints pkc1 primary key ); 此约束有名字: pkc1
3. foregin key (fk) 外键约束:(先定义父表,再定义子表)
carete table parent(c1 number primary key );
create table child (c number primary key , c2 number references parent(c1));
或表级约束定义:
create table child( c number primary key , c2 number , foreign key(c2) references
parent(c1));
create table test(c1 number primary key); 设置主键
create table test(c1 number constraints test_c1 primary key); 定义约束名,默认约束名为
SYS_ 在列后面定义约束称为列级约束
create table test(c1 number primary key(c1)); 所有列定义完后再定义约束称为表级约
束(能定义联合主键)
cretae table test(c1 number,c2 number,priary key(c1,c2)); 定义联合主键
create table child(c1 number primary key); 先要定义父表
create table child(c1 number primary key, c2 number references parent(c1)); 然后定义子
表references parent 定义外键
create table child(c1 number primary key, c2 number references parent(c1) on delete
cascate); on delete cascate 为级联删除
create table child(c1 number primary key, c2 number references parent(c1) on delete set
null); on delete set null 删除后将外键置空
create table child (c1 number primary key, c2 number,foreignkey(c2) references parent(c1));
4. 两表没有任何关联时会产生迪卡尔乘积:
select first_name , name from s_emp , s_dept;
5. insert 操作,插入记录(DML 操作)
insert into student value(1,'xxx','xxx');
insert into student(id,name,address) value(1,'xxx','xxx');
注意:有空值的话:
隐式插入
INSERT INTO s_dept (id, name) VALUES (12, 'MIS');
不往想为空的字段中插数据,系统默认为NULL
显示插入
INSERT INTO s_dept VALUES (13, 'Administration', NULL);
select * from s_emp where 1=2; 这样选不出纪录,方便察看表结构
6. update 修改操作
update table 表名set 字段名1=数据1 或表达式1, 字段名2=数据2 或表达式2
[where ....=....];
update shenfenzhen set num=99 where sid=2;
7. delete 删除操作
delete from 表名[where ...=...];
用delete 操作删除的记录可以通过rollback 命令回滚操作,会恢复delete 操作删除的
数据。
delete 操作不会释放表所占用的空间,delete 不适合删除记录多的大表。
delete 操作会占用大量的系统资源。
8. alter table 命令
alter table 命令用于修改表的结构(这些命令不会经常用):
增加字段:
alter table 表名add(字段字,字段类型)
删除字段:
alter tbale 表名drop column 字段; (8i 以后才支持)
给列改名:9.2.0 才支持
alter table 表名rename column 旧字段名to 新字段名;
修改字段
alter table 表名modify( 字段,类型)
(此时应注意的问题,更改时要看具体值情况之间的转达换, 改为字符类型时,必
须要为空)
not null 约束是使用alter table .. modify (..,not null),来加上的。
增加约束:
alter table 表名add constraint [约束名] 约束(字段);
只能够增加表级约束。
解除约束:(删除约束)
alter table 表名drop 约束;
(对于主键约束可以直接用此方法,因为一张表中只有一个主键约束名, 注意如果主
键此时还有其它表引用时删除主键时会出错)
alter table father drop primary key cascade;
(如果有子表引用主键时,要用此语法来删除主键,这时子表还存在只是子表中的外键
约束被及联删除了)
alter table 表名drop constraint 约束名;
(怎样取一个约束名:
a、人为的违反约束规定根据错误信息获取!
b、查询视图获取约束名!)
使约束失效或者生效
alter table 表名disable from primary key; (相当于把一个表的主键禁用)
alter table 表名enable primary key;
(enable 时会自动去检查表的记录是不是符合要求,如果有脏数据时必须要先删除脏
数据才可以enable)
更改表名
rename 旧表名to 新表名;
删除表:
trucate table 表名;
(表结构还在,数据全部删除,释放表所占的空间,不支持回退,常用删除大表)
/******************************************************/
Day05
/******************************************************/今天的note 不全,请自己补充
1. 哪些列更适合做索引
##表大,结果集小
经常出现在where 子句的列
经常用于表连接的列
主键列PK、唯一键列UK
create table test(
create unique index test_c1_idx on test(c1);
2. 新的建表语句
create table test_01
as
select * from test;
3. 一些概念
建索引的目的就是为了加快查询速度。
索引就相于一本的书的目录。索引点系统空间,属于表的附属物。删除一个表时,
相对应的索引也会删除。索引是会进行排序。
4. 查看表的rowid
##每条记录都有自己的rowid
select rowid,first_name from s_emp;
5. 创建视图
creating views 视图名;
视图就相当于一条select 语句,定义了一个视图就是定义了一个sql 语句,视图不占空
间,使用view 不会提高性能,但是能简单化sql 语句
(扩展知识: oracle 8i 以后的新视图)
MV 物化视图(占存储空间,把select 结果存在一个空间,会提高查询视图,增强实时
性,但是存在刷新问题,物化视图中的数据存在延迟问题,主要应用在数据仓库中
用要用于聚合表)
使用视图的好处:控制数据访问权限。
如何创建一个视图的例子:
create or replace views test_vi as select * from test1 where c1=1;
or replace 的意义,如果view 存在就覆盖,不存在才创建。
force|no force ,基表存在是使用,不存在是则创建该表。
此时往表test1(base table 基表)中插入数据时:表中没能变化,视图中的数据发生
改变
从视图中插数据时相对应的表会发生改变:
往视图中插数据时,会直接插进基表中,查看视图中的数据时,相当于就是执行创
建时的select 语句。
限制对数据库的访问,简化查询。
简单视图:来自于单表,且select 语句中不能包括函数,能进行DML 操作。
复杂视图:来源于多张表,不能执行DML 操作。
6. 删除视图drop views 视图名
7. 行列转置问题
8. 子查询还可以跟在from 后面
select e.first_name ,e.salary , a.asal
from s_emp e join
(select dept_id , avg(salary) asal from s_emp group by dept_id) a
on e.dept_id = a.dept_id
and e.salary > a.asal;
9. Rownum
##出现两条记录
select first_name , rownum from s_emp where rownum <=2;
##无记录,因为rownum 的特点是必须从1 条记录开始找
select first_name , rownum from s_emp where rownum between 4 and 9;
##排名问题:找出前N 条记录
##找出工资最高的前10 个人?
select rownum , first_name , salary
from (select first_name , salary
from s_emp
order by salary desc)
where rownum<=10;
##分页问题
##找出第11 条到第20 条的记录(先找出前20 条记录,再过滤掉前10 条)
##关键点:给rownum 起别名
##越往后走越慢,这种做法效率较低
select rn , first_name , salary
from (select rownum rn , first_name , salary
from s_emp
where rownum <=20)
where rn between 11 and 20;
10. (集合运算)Union 和Union ALL 拼结果集
##去重
select deptno from dept
union
select deptno from emp;
##不去重
select deptno from dept
union all
select deptno from emp;
11. (集合运算)intersect 去重后的交集
select deptno from dept
intersect
select deptno from emp;
12. (集合运算)minus 找出不包含的
select deptno from dept
minus
select deptno from emp;
13. Rename 改名
##改表名
rename abc to testabc;
##给列改名
alter table testabc rename column c1 to c10;
/******************************************************/
外延与复习
/******************************************************/1. 查询系统表
##查询本用户下所拥有的所有表的表名
select table_name from user_tables;
2. SQLPLUS
a) SQLPLUS 的buffer 中会缓存最后一条sql 语句
i. 可以使用"/"来执行这最后一条命令
ii. 可以使用edit 命令来编辑最后一条sql 语句
iii. L 命令(list)(sqlplus 命令)可以显示buffer 中最后一条命令
b) desc [表名]
##sqlplus 命令,注意他不是sql 语句,用于查看表的结构。descript 的缩写
desc s_emp;
3. 将SQL 语句写入指定的文件
spool a.lst
4. sql 脚本
a) 也就是在文件中写有sql 语句的文件,可以在sqlplus 中运行
b) 引入sql 脚本
i. sqlplus 用户名/密码@sql 脚本
ii. 注意:在用户名密码输入结束后一定要加空格然后再写@sql 脚本
iii. 在脚本中最后一行写上“exit”,则运行完脚本以后,回到shell 上
5. Oracle 数据库中的空表
dual 测试表
select sysdate from dual;
6. 单行函数
1)字符函数
字符是大小写敏感的
转小写lower(字段名) --- 其中的参数可以是一个字符串常量或是一个字段名
转大写upper(字段名)
首字母大写initcap(字段名)
字符串拼接concat(字段1, 字段2)
截取子串substr(字段名, 起始位置,取字符个数)
dual 表,是专门用于函数测试和运算的,他只有一条记录
字符串拼接concat(...,....)
求指定子串substr(...,起始位置,取字符个数)
可以使用"-"表示从右向左取,取的时候可以从左往友取。
例:select substr(first_name,-2,2) sub from s_emp;(取后两个)
select substr(first_name,2,2) sub from s_emp;(取前两个)
2)数值函数
四舍五入round(数据,保留小数点后几位)
可以用负数表示小数点前,0,表示小数点后第一位,也就是保留个位,-1 表示个
位(保留到十位)。
例:select round(15.36,1) from dual;
截取数字函数trunc(数据,保留的位数(小数点后位数)) 截取个位之后补0
例:select trunc(123.456,1) from dual;
3)日期函数
日期格式,
全日期格式世纪信息,年月日,时分秒。
缺省日期格式,日-月-年dd-mon-rr
修改当前会话的日期格式,会按照指定的格式输出日期
alter session set nls_date_format='yyyy mm dd hh24:mi:ss';
返回当前日期sysdate
例:select sysdate from dual;
select sysdate+1 from dual; 获得明天的日期,加1,单位是天
日期是格式敏感的
求两个日期间相隔了多少个月months_between(date1,date2)
加减指定数量的月份add_months(date,月数),月数可以为负,负值就是减去相应的
月数。
从date 日期开始的第一个星期五next_day(date,FriDay)
返回月末的日期last_day(date)
截取日期trunc(date,'年或月或日或时分秒')
例:select next_day(sysdate,2) from dual;
例:select trunc(add_months(sysdate,1),'month') from dual;
ROUND('25-MAY-95','MONTH') 01-JUN-95
ROUND('25-MAY-95 ','YEAR') 01-JAN-95
TRUNC('25-MAY-95 ','MONTH') 01-MAY-95
TRUNC('25-MAY-95 ','YEAR') 01-JAN-95
练习:
返回下个月的第一天的日期
select round(last_day(sysdate),'MONTH') from dual;
select add_months(trunc(sysdate,'MONTH'),1);
4)不同数据类型间转换函数
将日期转成字符tochar(date,'日期格式')
日期格式要用有效格式,格式大小写敏感'yyyy mm dd hh24:mi:ss',
'year'(全拼的年),'mm'(数字表示的月) 'month'(全拼的月),'day'(星期的全拼),'ddspth'
(日期的全拼) 'yy mm dd'
例:select to_char(sysdate,'yyyy mm dd hh24:mi:ss')from dual;
将字符转换成数字to_number('...')
将数字转字符to_char(number,'fmt') fmt 是数字格式
将字符串转成日期to_date('...','日期格式')
例:select to_char(to_date('2006 11 03','yyyy mm dd'),'dd-month-yy') from dual;
7. Oracle 中的主键自动增长
使用序列sequence
drop table xxxbyx_1;
create table xxxbyx_1(
id number primary key,
name varchar2(20)
);
drop sequence xxx_1;
create sequence xxx_1;
insert into xxxbyx_1 values (xxx_1.nextVal , 'aaa');
insert into xxxbyx_1 values (xxx_1.nextVal , 'bbb');
insert into xxxbyx_1 values (xxx_1.nextVal , 'ccc');
select xxx_1.currval from dual;
相关文章推荐
- Oracle11g基础知识2【SQL学习笔记】
- SQL的详细语法介绍——对于学习数据库最基础知识[转]
- MySql入门教程mysql基础知识学习实例讲解
- Oracle11g基础知识【SQL学习笔记】
- SQL的详细语法介绍——对于学习数据库最基础知识一
- SQL学习基础知识
- SQL的详细语法介绍——对于学习最基础知识二
- 1109学习记录 java script 基础知识实例
- Oracle 数据库 基础学习 (一) SQL基本知识
- SQL的详细语法介绍——对于学习数据库最基础知识一
- SQL的详细语法介绍——对于学习数据库最基础知识二
- 【SQLServer】T-SQL查询学习总结(2)[基础知识]
- pl/sql基础知识学习笔记(一)
- SQL的详细语法介绍——对于学习数据库最基础知识一
- 学习笔记二十三-sql基础知识
- pl/sql基础知识学习笔记(二)
- SQL学习基础知识:创造字符段
- SQL的详细语法介绍——对于学习最基础知识一
- pl/sql基础知识学习笔记(三)
- mysql--SQL编程(基础知识) 学习笔记1