Oracle【基础函数、视图、索引】

本文介绍了Oracle数据库的基本概念,如实例、表空间,并展示了如何创建表、用户以及分配权限。接着,详细阐述了如何进行单表查询、去除重复记录、排序、聚合统计、连接查询、子查询、分页查询、单行函数、条件取值、行列转换、分析函数和集合运算。此外,还探讨了视图的创建与使用,以及索引的重要性和不同类型。这些内容涵盖了Oracle数据库管理和查询的常用操作,对于理解和掌握Oracle数据库十分有益。
摘要由CSDN通过智能技术生成

1. 认识oracle数据库

Oracle是非常强大的数据库软件。默认端口:1521。与MySQL不同的是,Oracle数据库的概念是一个操作系统装的就是一个大的数据库。一个数据库可以有很多个实例,每个实例占用一系列的进程和内存。通常一台机器只用一个实例。每个实例可以有很多个用户。每个用户可以有很多张,这个用户类似MySQL的databases。在建表的时候指定对应的表空间(逻辑空间),该表的数据就会都存在表空间对应的数据文件上。

2. oracle基本概念

  • 实例:(Oracle Instance)包括进程和内存,一个oracle数据库有多个实例。
  • 表空间:oracle对物理上的相关数据文件的逻辑映射

设计自来水收费系统完成oracle基础需求
表设计:
在这里插入图片描述
– 创建表空间

create tablespace waterboss
datafile 'c:\waterboss.dbf'
size 100m
autoextend on
next 10m

– 创建用户

create user hfnu112
identified by root
default tablespace waterboss

– 给用户赋予权限dba

grant dba to hfnu112

单表查询

-- PLSQL中文乱码问题(显示问号)解决办法
select userenv('language') from dual;
-- 1. 简单条件查询
-- 1.1 精确查询
-- 查询水表编号30408的业主记录
select * from t_owners where watermeter = '30408'; 
select id,name,adddate from t_owners where watermeter = '30408'; 
-- 1.2 模糊查询
-- 查询业主名称包含姓刘的业主记录
select * from t_owners where name like '%刘%';   
-- 1.3 and运算符
-- 查询业主名称包含刘并且门牌号包含1的业主记录
select * from t_owners where name like '%刘%' and housenumber = '%1%';
-- 1.4 or运算符
-- 查询业主名称包含刘或者门牌号包含1的业主记录
select * from t_owners where name like '%刘%' or housenumber = '%1%';
-- 1.5 and 和 or 运算符混合使用
-- 查询业主名称包含刘或门牌号包含1的业主记录, 并且地址编号为3
select * from t_owners where (name like '%刘%' or housenumber like '%1%') and address_id = 3;
-- 1.6 范围查询
-- 查询台账记录用水字数大于等于3000, 并且小于等于5000的记录
select * from t_account where usenum >= 3000 and usenum <= 5000;
select * from t_account where usenum between 3000 and 5000;
-- 1.6 范围查询
select * from t_account;
-- 查询台账记录用水字数大于等于3000, 并且小于等于5000的记录
select * from t_account where usenum >= 3000 and usenum <= 5000;
select * from t_account where usenum between 3000 and 5000;
2. 去除重复记录
-- 查询业主表的地址id, 不重复显示
select distinct address_id from t_owners;
select distinct address_id, ownertype_id from t_owners;
-- 3. 排序
select * from t_account;
-- 对t_account表按使用量进行升序排序
select * from t_account order by usenum;

-- 对t_account表按使用量进行降序排序
select * from t_account order by usenum desc;
-- 4. 基于伪列的查询
-- 伪列就是像表中的列一样,但是在表中并部存储。伪列只能用于查询
-- ROWID:伪列返回的就是该行的物理地址,可以唯一的标识表中的一行
select rowid, own.* from t_owners own;  -- 给表名起别名
select rowid, id, name, address_id from t_owners;

-- ROWNUM: 结果集中每一行标识一个行号,第一行返回1,第二行返回2, ... 通过rownum可以限制查询结果集中返回的行
select rownum, id, name, address_id from t_owners;
-- 5. 聚合统计
-- 5.1 聚合函数
select * from t_account;
-- 统计2022年所有的用户的用水量总和
select sum(usenum) from t_owners where year = '2022';

-- 统计2022年所有的用户的平均用水量
select avg(usenum) from t_owners where year = '2022';

-- 统计2022年所有的用户的最高用水量
select maximize(usenum) from t_owners where year = '2022';

-- 统计2022年所有的用户的最低用水量
select minimize(usenum) from t_owners where year = '2022';

-- 统计业主类型为1的业主数量
select count(*) from t_owners where ownertype_id = 1;

-- 5.2 分组聚合
select * from t_area;
select * from t_account;
-- 按区域分组统计水费的合计数 求和   
select area_id, sum(money) from t_account group by area_id;

-- 查询水费合计大于100的区域统计
select area_id, sum(money) from t_account group by area_id having sum(money)>100;

3. 连接查询

-- 1 内连接查询
-- 查询显示业主编号,业主名称,业主类型名称
select id, name from t_owners;
select name from t_ownertype;

select t_owners.id, t_owners.name,t_ownertype.name  
from t_owners, t_ownertype 
where t_owners.ownertype_id = t_ownertype.id;

-- 查询显示业主编号,业主名称、地址和业主类型
select * from t_owners
select * from t_ownertype
select * from t_area

select ow.id, ow.name, ad.name, ot.name 
from t_owners ow, t_ownertype ot, t_address ad 
where ow.address_id = ad.id and ow.ownertype_id = ot.id;

-- 查询显示业主编号、业主名称、地址、所在区域,业主分类
select * from t_owners
select * from t_address
select * from t_area
select * from t_ownertype


select ow.id 业主编号, ow.name 业主名称, ad.name 地址, ar.name 区域, ot.name 业主分类 
from t_owners ow, t_address ad, t_area ar, t_ownertype ot 
where ow.address_id = ad.id and ow.ownertype_id = ot.id and ad.area_id = ar.id;  

--查询显示业主编号、业主名称、地址、所属区域、收费员、业主分类
select * from t_owners
select * from t_address
select * from t_area
select * from t_ownertype
select * from t_operator

select ow.id 业主编号, ow.name 业主名称, ad.name 地址, ar.name 区域, op.name 收费员, ot.name 业主分类 
from t_owners ow, t_address ad, t_area ar, t_ownertype ot, t_operator op 
where ow.address_id = ad.id and ow.ownertype_id = ot.id and ad.area_id = ar.id and ad.operator_id = op.id;  
-- 2. 左外连接
-- 查询业主的的账务记录,显示业主的编号、名称、年、月、金额,如果此业主没有账务记录也要显示姓名
select * from t_account
select * from t_owners
-- sql1999语法
select ow.id 业主编号, ow.name, ac.year, ac.month, ac.money from t_owners ow left join t_account ac on ow.id = ac.owner_id;
-- oracle语法
select ow.id 业主编号, ow.name, ac.year, ac.month, ac.money from t_owners ow, t_account ac where ow.id = ac.owner_id(+);
-- 3. 右外连接
-- 查询业主的的账务记录,显示业主的编号、名称、年、月、金额,如果此业主没有账务记录也要显示姓名
-- sql1999语法
select ow.id 业主编号, ow.name, ac.year, ac.month, ac.money from t_owners ow right join t_account ac on ow.id = ac.owner_id;
-- oracle语法
select ow.id 业主编号, ow.name, ac.year, ac.month, ac.money from t_owners ow, t_account ac where ow.id(+) = ac.owner_id;

4. 子查询(嵌套查询)

-- 1 where子句单行子查询
-- 查询2022年7月份用水量大于平均值的台账记录
select * from t_account;
-- 查询2022年7月用水量的平均值
select avg(usenum) from t_account where year = '2022' and month = '07';

-- 查询2022年7月份用水量大于3833.33333333333
select *  from t_account 
where year = '2022' and month = '07' and usenum > (select avg(usenum) from t_account where year = '2022' and month = '07');
-- 2 where子句多行子查询
-- 查询地址编号1,3,4的业主记录
select * from t_owners where address_id in (1,3,4);

-- 查询地址含有花园的地址编号 2, 3
select id from t_address where name like '%花园%'; 

select * from t_owners where address_id in (select id from t_address where name like '%花园%');

-- 查询地址不含有花园的业主记录
select * from t_owners where address_id not in (select id from t_address where name like '%花园%');
-- 3  from子句的子查询
-- 查询显示业主编号,业主名称,业主类型名,条件为业主类型为居民  id=1
-- 多行子查询
select * 
from 
(select ow.id 业主编号, ow.name 业主名称, ot.name 业主类型 from t_owners ow, t_ownertype ot where ow.ownertype_id = ot.id)
where 业主类型 = '个人客户';
-- 4 select子句子查询
-- 单行子查询
-- 列出业主信息,包括id、名称、所属地址
select id,name from t_owners;
select name from t_address;

select id,name,
(select name from t_address where id = address_id) 
from t_owners;

-- 列出业主信息包括id 名称 所属地址  所属区域
select id, name,
(select name from t_address where id = address_id) addressname,
(select (select name from t_area where id = area_id) from t_address where id = address_id) areaname
from t_owners;

5. 分页查询

-- 分页查询台账表t_account,每页5条记录
-- 1.简单分页
select rownum, ac.* from t_account ac where rownum <= 5;

select * from
(select rownum r, ac.* from t_account ac)
where r>5 and r <=10;

-- 2.基于排序的分页
select * from t_account order by usenum desc;

select * from
(select rownum r, ac.* from (select * from t_account ac order by usenum desc) ac)
where r <= 10 and r > 5;

6. 单行函数

-- 1. 字符函数
-- 伪表: 测试字符函数时,为了使sql语法完整,没有实际意义 
select * from dual;
-- length 获取字符串的长度
select length('abcd') from dual;

-- substr 截取字符串 起始位置1
select substr('meitong', 2, 2) from dual;

-- concat 拼接字符串 
select concat('hfnu', 'cn') from dual;
select concat(concat('hfnu', 'cn'), 'edu') from dual;
select 'hfnu'||'cn'||'aaa'||'bbb' from dual;
-- 2. 数值函数
-- 四舍五入round
select round(123.567) from dual;
select round(123.456, 2) from dual;

-- 截取数字trunc
select trunc(1001.456) from dual;
select trunc(1001.456, 2) from dual;

-- 取模mod
select mod(618,7) from dual;
-- 3. 日期函数
-- 获取当前日期和时间 sysdate
select sysdate from dual;

-- 在当前日期加上指定月add_months
select add_months(sysdate, 2) from dual;
select add_months(sysdate, -2) from dual;

-- 求所在月的最后一天last_day
select last_day(sysdate) from dual;
select last_day(sysdate-4) from dual;

-- 日期截取trunc
select trunc(sysdate) from dual;
select trunc(sysdate,'mm') from dual;
-- 4. 转换函数
-- 数字转字符串
select to_char(100)||'abc' from dual;

select 100||'' from dual;
-- 日期转字符串
select to_char(sysdate) from dual;
select to_char(sysdate, 'yyyy-MM-dd') from dual;
select to_char(sysdate, 'yyyy-MM-dd hh:mi:ss') from dual;

-- 字符串转日期
select to_date('2022-07-07', 'yyyy-mm-dd') from dual;

-- 字符串转数字
select to_number('123') from dual;
select to_number('123')+10 from dual;
select '100'+10 from dual;
-- 5. 其他函数
-- 空值处理
select nvl(null, 0) from dual;

-- 从显示价格表中业主类型id为1的价格记录,如果上限值为null,则显示00000
select nvl(maxnum, 0) from t_price where ownertype_id = 1;
select nvl(maxnum, 9999999999) from t_price where ownertype_id = 1;
select nvl2(maxnum, to_char(maxnum), '不限') from t_price where ownertype_id = 1;

7. 条件取值

-- 显示以下信息,不要关联查询业主类型表
select name,ownertype_id from t_owners;
select name,decode(ownertype_id, 1, '个人客户', 2, '企业客户') from t_owners;
select name,decode(ownertype_id, 1, '个人客户',100) from t_owners;

select name, (case ownertype_id
                   when 1 then '个人'
                   when 2 then '企业'
                   else '其他'  
                   end) from t_owners;    

8. 行列转换

-- 按月份的水费账务
select 
(select name from t_area where id = area_id) 区域, 
sum(case when month = '01' then money else 0 end),
sum(case when month = '02' then money else 0 end),
sum(case when month = '03' then money else 0 end),
sum(case when month = '04' then money else 0 end),
sum(case when month = '05' then money else 0 end),
sum(case when month = '06' then money else 0 end),
sum(case when month = '07' then money else 0 end),
sum(case when month = '08' then money else 0 end),
sum(case when month = '09' then money else 0 end),
sum(case when month = '10' then money else 0 end),
sum(case when month = '11' then money else 0 end),
sum(case when month = '12' then money else 0 end)
from t_account where year = '2022' group by area_id;
-- 按季度
select 
(select name from t_area where id = area_id) 区域,
sum(case when month >= '01' and month <= '03' then money else 0 end),
sum(case when month >= '04' and month <= '06' then money else 0 end),
sum(case when month >= '07' and month <= '09' then money else 0 end),
sum(case when month >= '10' and month <= '12' then money else 0 end)
from t_account where year = '2022' group by area_id;

9. 分析函数

-- 1. rank 相同的值排名,排名跳跃
-- 对t_account表的usenum字段排序,相同的值排名相同,排名跳跃
select t.* from t_account t order by usenum desc;
select rank() over(order by usenum desc) 排名, t.* from t_account t;

-- 对t_account表的usenum字段排序,值相同排名相同,排名连续
select dense_rank() over(order by usenum desc) 排名, t.* from t_account t;

-- 对t_account表的usenum字段排序,返回连续的排名,无论值是否相等
-- 用row_number实现分页查询相对三层嵌套子查询语法简单
select row_number() over(order by usenum desc) 排名, t.* from t_account t;
-- 分页查询
select * 
from  
(select row_number() over(order by usenum desc) 排名, t.* from t_account t)
where 排名 > 5 and 排名 <=10; 

10. 集合运算

-- 1. 并集运算
-- 业主表
-- union all 包括重复的记录  ;  union 不包括重复记录
select * from t_owners where id > 1004
union all
select * from t_owners where id < 1009;

-- 2. 交集运算
select * from t_owners where id > 1004
intersect
select * from t_owners where id < 1009;

-- 3. 差集运算
select * from t_owners where id < 1009
minus
select * from t_owners where id > 1004;

-- 差集分页查询
select rownum, t.* from t_account t where rownum <= 10
minus
select rownum, t.* from t_account t where rownum <= 5;

11. 视图

视图是从一个或者多个表中导出的,视图的行为与表非常相似,但视图是一个虚拟表。在视图中,用户可以使用SELECT语句查询数据,以及使用INSERT、UPDATE和DELETE语句修改记录。视图可以使用户操作方便,而且可以保障数据库系统的安全。

  • 视图就是封装了一条复杂查询的sql语句。
-- 1)简单视图
-- 创建视图:业主类型为1的业主信息
create view view_owner1 as
select * from t_owners where ownertype_id = 1;
-- 查询视图view_owner1 业主类型为1的业主记录
select * from view_owner1 where ownertype_id = 1;

-- 修改视图view_owner1
update view_owner1 set name = '张三' where id = 1002;
commit;

select * from t_owners;
-- 2) 带检查约束的视图
-- 根据地址表,创建视图,内容为区域id为2的记录
create view view_address2 as
select * from t_address where area_id = 2
with check option;

select * from view_address2 where area_id =2;

-- 修改视图view_address2 ; area_id这个条件不能修改 
update view_address2 set area_id = 3 where name = '景尚花园';
commit;
-- 3)只读视图
-- 根据地址表,创建视图,内容为区域id为2的记录
create or replace view view_address2 as
select * from t_address where area_id = 2
with read only;

select * from view_address2 where area_id =2;

-- 修改视图view_address2  
update view_address2 set name = '花园小区' where id = 2;
commit;
-- 创建带错误的视图
create force view view_stu as
select * from student;
drop view view_stu;

多表关联视图

-- 创建视图,查询业主编号,业主名称、业主类型名称
create or replace view view_owner2 as
select ow.id 业主编号, ow.name 业主名称, ot.name 业主类型名称 
from t_owners ow, t_ownertype ot 
where ow.ownertype_id = ot.id;

select * from view_owner2 where 业主类型名称 like '%个人%';

-- 修改视图view_owner2
update view_owner2 set 业主名称='刘明' where 业主编号 = '1008';
commit; 
-- 键保留表
-- 5) 分组聚合统计
-- 创建视图,按年月统计水费金额
create or replace view view_account1 as
select year, month, sum(money) 水费 
from t_account 
group by year, month
order by year, month;

select * from view_account1;
-- 修改视图view_account1  聚合统计不能修改
update view_account1 set 水费='80' where year='2022' and month='08'
commit;

12. 索引

(1)是一种快速查询表中内容的机制,类似于新华字典的目录 (2)运用在表中某个/些字段上,但存储时,独立于表之外

为什么用索引?

  • 1)通过指针加速Oracle服务器的查询速度
  • 2)通过rowid快速定位数据的方法,减少磁盘I/O

什么时候创建索引?

	1)表经常进行 SELECT 操作
	2)表很大(记录超多),记录内容分布范围很广
	3)列名经常在 WHERE 子句或连接条件中出现
-- 1) 普通索引
-- 创建索引
create index index_owners_name on t_owners(name);

select * from t_owners where name = '刘华';

-- 2) 唯一索引
-- 主键就是唯一索引
-- 在业主表中水表编号创建唯一索引; 对应一个唯一约束
create unique index index_owners_watermete on t_owners(watermeter);

update t_owners set watermeter = '30406' where id=1001;
commit;

-- 3) 复合索引
create index idx_compo_owner on t_owners(address_id, housenumber);

-- 4) 反向键索引:   当字段值连续增长
create index idx_id on t_owners(id) reverse;

-- 5) 位图索引:  低基数  不能进行范围查询
create bitmap index idx_owner_type on t_owners(ownertype_id);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Husp0707

你的小小点赞、关注是我的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值