s_emp s_dept s_region salgrade
first_name 名 id 部门编号 id 地区编号 grade 工资级别
salary 月薪 name 部门名 name 地区编号 losal 级别对应的低工资
dept_id 部门编号 region_id 地区编号 hisal 级别对应的高工资
id 员工编号
manager_id 直接领导的员工编号
1.显示每个员工的first_name salary 和 对应的部门名
2.显示每个员工的 first_name salary 和 salary 对应的工资级别
3.显示s_emp 表中所有的领导 显示 id first_name
不能忘记 distinct
4.显示s_emp 表中所有的普通员工 显示 id first_name
select m.id,m.first_name
from s_emp e,s_emp m
where e.manager_id(+) = m.id and e.manager_id is null;
5.显示每个员工的 first_name salary 和 salary 对应的工资级别 超出统计范围的
员工信息也要显示
6.使用sql99 的内连接 实现 题目 1 7.使用sql99 的左外连接 实现 题目 4
select m.id,m.first_name
from s_emp m left join s_emp e
on e.manager_id = m.id where e.manager_id is null;
8.写出sql中 常用的 5 个组函数 9.按照部门编号分组 统计 每个部门的人数
10.按照部门编号分组 统计每个部门的平均工资 显示平均工资大于1500的部门 最终显示 部门编号
和 平均工资
---------------------------------------------------------------------------------
1.分组
1.1 按照部门编号分组 统计每个部门的平均工资 显示平均工资大于1500的部门 最终显示 部门编号
和 平均工资
select dept_id,avg(salary) from s_emp
group by dept_id having avg(salary)>1500;
select dept_id,avg(salary) asal from s_emp
group by dept_id having avg(salary) >1500 order by asal;
sql的执行顺序:
from where group by having select order by
1.2 按照部门编号分组 统计每个部门的平均工资 显示 部门编号 平均工资 还要部门名
由于部门编号 可以决定部门名 所以 分组时 在部门编号后面加 部门名 不会影响分组
select dept_id,avg(salary),name
from s_emp,s_dept where dept_id = s_dept.id
group by dept_id,name;
select dept_id,avg(salary),min(name) name
from s_emp,s_dept where dept_id = s_dept.id
group by dept_id;
结论:在分组语句中 select 后的字段 要么是分组标准 要么是经过合适的组函数处理过的
2.子查询
2.1 概念
把一个查询结果 作为另一个查询的基础。
2.2 子查询出现的位置
where 之后
having 之后
from 之后
2.3 举例 where 之后
/* 查询出所有的领导编号 多一个NULL值 */
select distinct manager_id from s_emp;
/* 再写一个查询 让员工的编号 出现在上面的列表范围内 8个领导 */
select id,first_name from s_emp where id in
((select distinct manager_id from s_emp));
/* 通过子查询 找出所有的普通员工 */
select id,first_name from s_emp where id not in
((select distinct manager_id from s_emp where manager_id is not null));
2.4 having 之后
按照部门编号 分组 统计每个部门的平均工资 显示大于41 部门平均工资的部门
最终显示 部门编号 和 平均工资。
select dept_id,avg(salary) from s_emp
group by dept_id having avg(salary) >
(select avg(salary) from s_emp where dept_id=41);
2.5 from 之后 (分页)
任何合法查询语句 都对应一张内存表 . nn
select id,first_name name ,salary from s_emp;
select id,salary from
(select id,first_name name ,salary from s_emp) where salary>1000;
3.DDL 语句
3.1 create table 建立表
语法:
create table 表名(
字段名 类型,
字段名 类型,
字段名 类型
);
类型: number 数字 varchar(n) 变长字符串 char(n) 定长字符串 date 日期类型
练习:
建立一张表 叫 myemp 表 字段有 id number fname varchar(30)
sname char(30) start_date date
create table myemp(
id number,
fname varchar(30),
sname char(30),
start_date date
);
3.2 删除表
drop table 表名;
drop table myemp;
3.3 修改表 alter table
删除表中的一个字段
alter table myemp drop column start_date;
增加表中的一个字段
alter table myemp add sdate date;
4.DML
4.1 insert 增加数据
全字段插入数据
insert into 表名 values(值1,值2,值3);
注意:字段的排列顺序 和 表头相同 注意字段的类型 如果是字符串 值必须使用单引号
举例:
insert into myemp values(100,'xsy','xsy',sysdate);
commit;
select length(fname),length(sname) from myemp;
select * from myemp where fname='xsy ';
select * from myemp where sname='xsy '; 这个有数据的原因 自动补空格
注意插入数据之后 一定要提交
全字段插入的另外一个手段? 只要字段没有规定不能为空 则可以使用 NULL
insert into myemp values(101,'zbs',NULL,sysdate);
commit;
选择部分字段插入 没有选择的字段 默认值是 NULL (必须包含所有的非空字段)
insert into 表名(字段名1,字段名3) values(值1,值3);
commit;
insert into myemp(id,sdate) values(110,sysdate);
commit;
练习:
给 s_emp 表 插入一条数据 给 id last_name 赋值成 26 'abc' 其它值为NULL
insert into s_emp values(26,'abc',NULL,NULL,NULL,NULL,
null,null,null,null,null);
commit;
insert into s_emp(id,last_name) values(27,'cba');
commit;
4.2 更新数据 update
update 表名 set 字段名1=值 where 条件;
update 表名 set 字段名1 = 值1,字段名2=值2 where 条件;
commit;
练习:
把s_emp 表中 id=20 员工 把 first_name 改成 abc salary 改成 54321
update s_emp set first_name='abc',salary=54321 where id=200;
commit;
4.3 删除数据 delete
delete from 表名 where 条件;
commit;
5.TCL事务控制语句 (transaction control language)
5.1 概念
transaction 叫 事务 也叫 交易。
事务就是多个操作 要看成一个逻辑整体,这些操作必须同时成功 或者同时失败。
5.2 具体的操作 转账
commit; 确认 提交
rollback; 回退 回滚
update account set money=money-5000 where id=1;
// 假设 能获取 执行的 结果 f
update account set money=money+5000 where id=2;
// 假设 能获取 执行的 结果 f2
if(f && f2) {
commit;
}else{
rollback;
}
5.3 保存点 savepoint (了解)
可以做到 部分成功 部分失败
发信息到基站
a
基站记录收到信息的日志
扣钱
b
基站发送信息到 目标手机
c
基站记录发送信息的日志
rollback to a;
commit;
insert into myemp values(1,'aa','aa',sysdate);
savepoint a;
insert into myemp values(2,'bb','bb',sysdate);
savepoint b;
insert into myemp values(3,'cc','cc',sysdate);
savepoint c;
insert into myemp values(4,'dd','dd',sysdate);
rollback to b;
commit;
6.日期类型
6.1 日期类型的默认表现
dd-MON-yy
select id,start_date from s_emp;
按照入职日期排序 显示 id first_name start_date
select id,first_name,start_date from s_emp order by start_date;
6.2 使用 to_char 来改变显示的格式
新的日期格式:
yyyy 四位年
mm 两位月
dd 天
hh 12小时制
hh24 24小时制
mi 分钟
ss 秒
day 星期几
MON 英文月的缩写
month 英文月的全写
pm 上午 显示成 am 下午显示成pm
select id,first_name,to_char(start_date,'yyyy-mm-dd hh24:mi:ss MON pm')
from s_emp order by start_date;
bbbbbb
select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss day pm') from dual;
6.3 日期数据的插入
sysdate 可以代表 当前的时间点
过去和 未来的时间 如何处理?
2008-08-08 20:08:10
2090-08-08 08:10:25
dd-MON-yy 只能放入 年月日 时分秒 默认是 零
to_date(par1,par2) par1 是要处理的日期字符串 par2 是日期格式字符串
能把日期字符串 根据日期格式转换成 日期数据
i o myemp values(5,'test','test','08-AUG-08');
commit;
select id,to_char(sdate,'yyyy-mm-dd hh24:mi:ss') from myemp;
insert into myemp values(6,'test','test',
to_date('2008-08-08 20:08:10','yyyy-mm-dd hh24:mi:ss'));
commit;
insert into myemp values(7,'test','test',
to_date('2090-08-08 08:10:25','yyyy-mm-dd hh24:mi:ss'));
commit;
6.4 日期调整
先调整 秒 分钟 小时 天 默认以天为单位
select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss'),
to_char(sysdate+1,'yyyy-mm-dd hh24:mi:ss') from dual;
select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss'),
to_char(sysdate-2,'yyyy-mm-dd hh24:mi:ss') from dual;
select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss'),
to_char(sysdate+10/(24*60),'yyyy-mm-dd hh24:mi:ss') from dual;
add_months(par1,par2) par1 要处理的日期 par2 几个月 正数负数都可以
select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss'),
to_char(add_months(sysdate,2),'yyyy-mm-dd hh24:mi:ss') from dual;
trunc(par1,par2) par1 是要处理的日期 par2处理的精度 默认是天
select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss'),
to_char(trunc(sysdate),'yyyy-mm-dd hh24:mi:ss') from dual;
select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss'),
to_char(trunc(sysdate,'mm'),'yyyy-mm-dd hh24:mi:ss') from dual;
select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss'),
to_char(trunc(add_months(sysdate,-1),'mm'),'yyyy-mm-dd hh24:mi:ss')
from dual;
7.约束 constraint
7.1 概念
当数据进入 数据库表中时,数据库管理系统 可以通过加在字段上 约束 限制来对数据进行
检查 符合检查条件的数据才能进入数据库的表。
7.2 约束的种类
主键约束 primary key pk
如果对一个字段加了主键约束 则 这个字段的取值 必须不能为空 并且 值 不能
重复。一张表只能有一个主键。
唯一性约束 unique uk
如果对一个字段加了唯一性约束 则这个字段的值 不能重复
非空约束 not null nn
字段的值不能为空
检查约束 check ck
字段的值必须符合检查条件
外键约束 foreign key fk
references
7.3 约束的实现方式
列级约束实现 : 在定义表的某一列时 直接在这一列后面加约束限制
表级约束实现: 在定义完表的所有列之后 再选择某些列加约束限制。
7.4 主键的列级约束实现
create table column_cons(
id number primary key,
name varchar2(30),
salary number
);
insert into column_cons values(1,'t1',12312);
ERROR at line 1:
ORA-00001: unique constraint (SYSTEM.SYS_C007123) violated
SYSTEM.SYS_C007123 这代表约束的名字 系统默认提供一个不重复的
约束名 但不方便记忆 和 对数据的维护。
7.5 建立约束时 给约束起名字
名字构成 是 表名_字段名_约束简称
drop table column_cons;
create table column_cons(
id number constraint column_cons_id_pk primary key,
name varchar2(30),
salary number
);
insert into column_cons values(1,'t1',12312);
ERROR at line 1:
ORA-00001: unique constraint (SYSTEM.COLUMN_CONS_ID_PK) violated
7.6 建立一张表 叫 myemp100
字段有 id number pk fname varchar2(30) uk
sname char(30) nn
要求建表之前 先删除表 要求按照表名_字段名_约束简称 给约束起名字
测试约束是否起作用。