oracle数据查询

数据准备


--建立价格区间表
create  table t_pricetable
(
id number primary key,
price number(10,2),
ownertypeid number,
minnum number,
maxnum number
);


--业主类型
create table t_ownertype
(
id number primary key,
name varchar2(30)
);

--业主表
create table t_owners
(
id number primary key,
name varchar2(30),
addressid number,
housenumber varchar2(30),
watermeter varchar2(30),
adddate date,
ownertypeid number
);



--区域表
create table t_area
(
id number,
name varchar2(30)
);

--收费员表
create table t_operator
(
id number,
name varchar2(30)
);


--地址表
create table t_address
(
id number primary key,
name varchar2(100),
areaid number,
operatorid number
);


--账务表--
create table t_account 
(
id number primary key,
owneruuid number,
ownertype number,
areaid number,
year char(4),
month char(2),
num0 number,
num1 number,
usenum number,
meteruser number,
meterdate date,
money number(10,2),
isfee char(1),
feedate date,
feeuser number
);


create sequence seq_account;

--业主类型
insert into t_ownertype values(1,'居民');
insert into t_ownertype values(2,'行政事业单位');
insert into t_ownertype values(3,'商业');

--地址信息--
insert into t_address values( 1,'明兴花园',1,1);
insert into t_address values( 2,'鑫源秋墅',1,1);
insert into t_address values( 3,'华龙苑南里小区',2,2);
insert into t_address values( 4,'河畔花园',2,2);
insert into t_address values( 5,'霍营',2,2);
insert into t_address values( 6,'回龙观东大街',3,2);
insert into t_address values( 7,'西二旗',3,2);

--业主信息
insert into t_owners values(1,'范冰',1,'1-1','30406',to_date('2015-04-12','yyyy-MM-dd'),1 );
insert into t_owners values(2,'王强',1,'1-2','30407',to_date('2015-02-14','yyyy-MM-dd'),1 );
insert into t_owners values(3,'马腾',1,'1-3','30408',to_date('2015-03-18','yyyy-MM-dd'),1 );
insert into t_owners values(4,'林小玲',2,'2-4','30409',to_date('2015-06-15','yyyy-MM-dd'),1 );
insert into t_owners values(5,'刘华',2,'2-5','30410',to_date('2013-09-11','yyyy-MM-dd'),1 );
insert into t_owners values(6,'刘东',2,'2-2','30411',to_date('2014-09-11','yyyy-MM-dd'),1 );
insert into t_owners values(7,'周健',3,'2-5','30433',to_date('2016-09-11','yyyy-MM-dd'),1 );
insert into t_owners values(8,'张哲',4,'2-2','30455',to_date('2016-09-11','yyyy-MM-dd'),1 );
insert into t_owners values(9,'昌平区中西医结合医院',5,'2-2','30422',to_date('2016-10-11','yyyy-MM-dd'),2 );
insert into t_owners values(10,'美廉美超市',5,'4-2','30423',to_date('2016-10-12','yyyy-MM-dd'),3 );


--操作员
insert into t_operator values(1,'马小云');
insert into t_operator values(2,'李翠花');



--地区--
insert into t_area values(1,'海淀');
insert into t_area values(2,'昌平');
insert into t_area values(3,'西城');
insert into t_area values(4,'东城');
insert into t_area values(5,'朝阳');
insert into t_area values(6,'玄武');


--价格表--

insert into t_pricetable values(1,2.45,1,0,5);
insert into t_pricetable values(2,3.45,1,5,10);
insert into t_pricetable values(3,4.45,1,10,null);

insert into t_pricetable values(4,3.87,2,0,5);
insert into t_pricetable values(5,4.87,2,5,10);
insert into t_pricetable values(6,5.87,2,10,null);

insert into t_pricetable values(7,4.36,3,0,5);
insert into t_pricetable values(8,5.36,3,5,10);
insert into t_pricetable values(9,6.36,3,10,null);

--账务表--
insert into t_account values( seq_account.nextval,1,1,1,'2012','01',30203,50123,0,1,sysdate,34.51,'1',to_date('2012-02-14','yyyy-MM-dd'),2 );
insert into t_account values( seq_account.nextval,1,1,1,'2012','02',50123,60303,0,1,sysdate,23.43,'1',to_date('2012-03-14','yyyy-MM-dd'),2 );
insert into t_account values( seq_account.nextval,1,1,1,'2012','03',60303,74111,0,1,sysdate,45.34,'1',to_date('2012-04-14','yyyy-MM-dd'),2 );
insert into t_account values( seq_account.nextval,1,1,1,'2012','04',74111,77012,0,1,sysdate,52.54,'1',to_date('2012-05-14','yyyy-MM-dd'),2 );
insert into t_account values( seq_account.nextval,1,1,1,'2012','05',77012,79031,0,1,sysdate,54.66,'1',to_date('2012-06-14','yyyy-MM-dd'),2 );
insert into t_account values( seq_account.nextval,1,1,1,'2012','06',79031,80201,0,1,sysdate,76.45,'1',to_date('2012-07-14','yyyy-MM-dd'),2 );
insert into t_account values( seq_account.nextval,1,1,1,'2012','07',80201,88331,0,1,sysdate,65.65,'1',to_date('2012-08-14','yyyy-MM-dd'),2 );
insert into t_account values( seq_account.nextval,1,1,1,'2012','08',88331,89123,0,1,sysdate,55.67,'1',to_date('2012-09-14','yyyy-MM-dd'),2 );
insert into t_account values( seq_account.nextval,1,1,1,'2012','09',89123,90122,0,1,sysdate,112.54,'1',to_date('2012-10-14','yyyy-MM-dd'),2 );
insert into t_account values( seq_account.nextval,1,1,1,'2012','10',90122,93911,0,1,sysdate,76.21,'1',to_date('2012-11-14','yyyy-MM-dd'),2 );
insert into t_account values( seq_account.nextval,1,1,1,'2012','11',93911,95012,0,1,sysdate,76.25,'1',to_date('2012-12-14','yyyy-MM-dd'),2 );
insert into t_account values( seq_account.nextval,1,1,1,'2012','12',95012,99081,0,1,sysdate,44.51,'1',to_date('2013-01-14','yyyy-MM-dd'),2 );

insert into t_account values( seq_account.nextval,2,1,3,'2012','01',30334,50433,0,1,sysdate,34.51,'1',to_date('2013-02-14','yyyy-MM-dd'),2 );
insert into t_account values( seq_account.nextval,2,1,3,'2012','02',50433,60765,0,1,sysdate,23.43,'1',to_date('2013-03-14','yyyy-MM-dd'),2 );
insert into t_account values( seq_account.nextval,2,1,3,'2012','03',60765,74155,0,1,sysdate,45.34,'1',to_date('2013-04-14','yyyy-MM-dd'),2 );
insert into t_account values( seq_account.nextval,2,1,3,'2012','04',74155,77099,0,1,sysdate,52.54,'1',to_date('2013-05-14','yyyy-MM-dd'),2 );
insert into t_account values( seq_account.nextval,2,1,3,'2012','05',77099,79076,0,1,sysdate,54.66,'1',to_date('2013-06-14','yyyy-MM-dd'),2 );
insert into t_account values( seq_account.nextval,2,1,3,'2012','06',79076,80287,0,1,sysdate,76.45,'1',to_date('2013-07-14','yyyy-MM-dd'),2 );
insert into t_account values( seq_account.nextval,2,1,3,'2012','07',80287,88432,0,1,sysdate,65.65,'1',to_date('2013-08-14','yyyy-MM-dd'),2 );
insert into t_account values( seq_account.nextval,2,1,3,'2012','08',88432,89765,0,1,sysdate,55.67,'1',to_date('2013-09-14','yyyy-MM-dd'),2 );
insert into t_account values( seq_account.nextval,2,1,3,'2012','09',89765,90567,0,1,sysdate,112.54,'1',to_date('2013-10-14','yyyy-MM-dd'),2 );
insert into t_account values( seq_account.nextval,2,1,3,'2012','10',90567,93932,0,1,sysdate,76.21,'1',to_date('2013-11-14','yyyy-MM-dd'),2 );
insert into t_account values( seq_account.nextval,2,1,3,'2012','11',93932,95076,0,1,sysdate,76.25,'1',to_date('2013-12-14','yyyy-MM-dd'),2 );
insert into t_account values( seq_account.nextval,2,1,3,'2012','12',95076,99324,0,1,sysdate,44.51,'1',to_date('2014-01-14','yyyy-MM-dd'),2 );

insert into t_account values( seq_account.nextval,100,1,3,'2012','12',95076,99324,0,1,sysdate,44.51,'1',to_date('2014-01-01','yyyy-MM-dd'),2 );
insert into t_account values( seq_account.nextval,101,1,3,'2012','12',95076,99324,0,1,sysdate,44.51,'1',to_date('2015-01-01','yyyy-MM-dd'),2 );

update t_account set usenum=num1-num0;
update t_account set money=usenum*2.45;
commit;

单表查询

基于伪列的查询

在 Oracle 的表的使用过程中,实际表中还有一些附加的列,称为伪列。伪列就像表中的列一样,但是在表中并不存储。伪列只能查询,不能进行增删改操作。接下来学习两个伪列:ROWID 和 ROWNUM。

ROWID

表中的每一行在数据文件中都有一个物理地址,ROWID 伪列返回的就是该行的物理地址。使用 ROWID 可以快速的定位表中的某一行。ROWID 值可以唯一的标识表中的一行。由于 ROWID 返回的是该行的物理地址,因此使用ROWID可以显示行是如何存储的

-- 查询语句
select rowid,t.* from t_owners t ;

查询结果如下:
在这里插入图片描述
可以通过指定 ROWID 来查询记录

select rowID,t.*
from t_owners t
where ROWID='AAADY/AAFAAAADYAAA';

查询结果如下:
在这里插入图片描述

ROWNUM

在查询的结果集中,ROWNUM 为结果集中每一行标识一个行号,第一行返回1,第二行返回 2,以此类推。通过 ROWNUM 伪列可以限制查询结果集中返回的行数

select rownum,t.*
from t_owners t;

查询结果如下:
在这里插入图片描述

聚合统计

ORACLE 的聚合统计是通过分组函数来实现的,与 MYSQL 一致。

求和 sum

需求:统计 2012 年所有用户的用水量总和

select sum(usenum) 用水量总和
from t_account where year='2012'

查询结果如下
在这里插入图片描述

扫描二维码关注公众号,回复: 16107963 查看本文章

求平均 avg

需求:统计 2012 年所有用水量(字数)的平均值

select avg(usenum) 用水量平均值
from t_account where year='2012'

查询结果如下
在这里插入图片描述

求最大值 max

统计 2012 年最高用水量(字数)

select max(usenum) 最高用水量
from t_account where year='2012'

查询结果如下
在这里插入图片描述

求最小值 min

统计 2012 年最低用水量(字数)

select min(usenum) 最低用水量
from t_account where year='2012'

查询结果如下
在这里插入图片描述

分组聚合 Group by

按区域分组统计水费合计数

select areaid 地区,sum(money) 水费 from t_account group by areaid

查询结果如下
在这里插入图片描述

分组后条件查询 having

查询水费合计大于 16900 的区域及水费合计

select areaid 地区,sum(money) 水费 from t_account group by areaid having sum(money)>169000

查询结果:
在这里插入图片描述

连接查询

多表内连接查询

(1)需求:查询显示业主编号,业主名称,业主类型名称,如下图:
在这里插入图片描述
查询语句:

select o.id 业主编号,o.name 业主名称,ot.name 业主类型 from T_OWNERS o,T_OWNERTYPE ot
where o.ownertypeid=ot.id

(2)需求:查询显示业主编号,业主名称、地址和业主类型,如下图
在这里插入图片描述
此查询需要三表关联查询。分别是业主表,业主分类表和地址表
语句:

select o.id 业主编号,o.name 业主名称,ad.name 地址,
ot.name 业主类型
from T_OWNERS o,T_OWNERTYPE ot,T_ADDRESS ad
where o.ownertypeid=ot.id and o.addressid=ad.id

(3)需求:查询显示业主编号、业主名称、地址、所属区域、业主分类,如下图:
在这里插入图片描述
分析:这里需要四个表关联查询,比上边多了一个区域表(T_AREA)
查询语句:

select o.id 业主编号,o.name 业主名称,ar.name 区域, ad.name 地址, ot.name 业主类型
from T_OWNERS o ,T_OWNERTYPE ot,T_ADDRESS ad,T_AREA ar 
where o.ownertypeid=ot.id and o.addressid=ad.id and ad.areaid=ar.id

(4)需求:查询显示业主编号、业主名称、地址、所属区域、收费员、业主分类,如下图:
在这里插入图片描述
分析:此查询比上边又多了一个表 T_OPERATOR
语句:

select ow.id 业主编号,ow.name 业主名称,ad.name 地址,
ar.name 所属区域,op.name 收费员, ot.name 业主类型
from T_OWNERS ow,T_OWNERTYPE ot,T_ADDRESS ad ,
T_AREA ar,T_OPERATOR op
where ow.ownertypeid=ot.id and ow.addressid=ad.id
and ad.areaid=ar.id and ad.operatorid=op.id

左外连接查询

需求:查询业主的账务记录,显示业主编号、名称、年、月、金额。如果此业主没有账务记录也要列出姓名。
在这里插入图片描述
分析:我们要查询这个结果,需要用到 T_OWNERS(业主表),T_ACCOUNT(台账表) 按照查询结果,业主表为左表、账务表为右表。按照 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.owneruuid

按照 ORACLE 提供的语法,就很简单了:

SELECT ow.id,ow.name,ac.year ,ac.month,ac.money FROM
T_OWNERS ow,T_ACCOUNT ac
WHERE ow.id=ac.owneruuid(+)

如果是左外连接,就在右表所在的条件一端填上(+)

右外连接查询

需求:查询业主的账务记录,显示业主编号、名称、年、月、金额。如果账务记录没有对应的业主信息,也要列出记录。如下图:
在这里插入图片描述
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.owneruuid

ORACLE 的语法

select ow.id,ow.name,ac.year,ac.month,ac.money from
T_OWNERS ow , T_ACCOUNT ac
where ow.id(+) =ac.owneruuid

子查询

where 子句中的子查询

单行子查询

  • 只返回一条记录
  • 单行操作符
    在这里插入图片描述
    需求:查询 2012 年 1 月用水量大于平均值的台账记录
    语句:
select * from t_account where
year='2012' and month='01' and 
usenum >(select  avg(usenum) from t_account where year='2012' and month='01')

查询结果:
在这里插入图片描述

多行子查询

  • 返回了多条记录
  • 多行操作符
    在这里插入图片描述
    in 运算符
    (1)需求:查询地址编号为 1 、3、4 的业主记录
select * from t_owners t where t.addressid in (1,3,4);

查询结果如下:
在这里插入图片描述
(2)需求:查询地址含有“花园”的业主的信息

select * from t_owners t 
where t.addressid in 
(select d.id from t_address d where d.name like '%花园%');

查询结果:
在这里插入图片描述
3)需求:查询地址不含有“花园”的业主的信息

select * from t_owners t 
where t.addressid not in 
(select d.id from t_address d where d.name like '%花园%');

查询结果:
在这里插入图片描述

from 子句中的子查询

from 子句的子查询为多行子查询
需求:查询显示业主编号,业主名称,业主类型名称,条件为业主类型为”居民”,
使用子查询实现。

select * from 
(select o.id 业主编号,o.name 业主名称,ot.name 业主类型
from t_owners o,t_ownertype ot
where o.ownertypeid=ot.id)v 
where v.业主类型='居民';

在这里插入图片描述

select 子句中的子查询

select 子句的子查询必须为单行子查询
(1)需求:列出业主信息,包括 ID,名称,所属地址。

select id,name,
(select name from t_address where id=addressid) addressname from t_owners

在这里插入图片描述
(2)需求:列出业主信息,包括 ID,名称,所属地址,所属区域。

select id,name,
( select name from t_address where id=addressid )
addressname,
( select (select name from t_area where id=areaid )from 
t_address where id=addressid )adrename
from t_owners;

在这里插入图片描述

分页查询

简单分页

需求:分页查询台账表 T_ACCOUNT,每页 10 条记录
在 ORACLE 进行分页查询,需要用到伪列ROWNUM和嵌套查询
我们首先显示前 10 条记录,语句如下:

select rownum,t.* from T_ACCOUNT t where rownum<=10;

在这里插入图片描述
那么我们显示第 11 条到第 20 条的记录呢?编写语句:

select rownum,t.* from T_ACCOUNT t
where rownum>10 and rownum<=20;

查询结果:
在这里插入图片描述
怎么没有结果?
这是因为 rownum 是在查询语句扫描每条记录时产生的,所以不能使用“大于”
符号,只能使用“小于”或“小于等于” ,只用“等于”也不行。
那怎么办呢?我们可以使用子查询来实现

select * from
(select rownum r,t.* from T_ACCOUNT t where rownum<=20)where r>10

在这里插入图片描述

基于排序的分页

需求:分页查询台账表 T_ACCOUNT,每页 10 条记录,按使用字数降序排序。
我们查询第 2 页数据,如果基于上边的语句添加排序,语句如下:

select * from
(select rownum r,t.* from T_ACCOUNT t where rownum<=20 order by usenum desc)
where r>10

查询结果如下:
在这里插入图片描述
经过验证,我们看到第 2 页的结果应该是下列记录
在这里插入图片描述
所以推断刚才的语句是错误的!那为什么是错误的呢?
我们可以先单独执行嵌套查询里面的那句话

select rownum r,t.* from T_ACCOUNT t 
where rownum<=20 order by usenum desc;

你会看到查询结果如下:
在这里插入图片描述
你会发现排序后的 R 是乱的。这是因为 ROWNUM 伪列的产生是在表记录扫描
是产生的,而排序是后进行的,排序时 R 已经产生了,所以排序后R是乱的。
那该如何写呢?
很简单,我们只要再嵌套一层循环(一共三层),让结果先排序,然后对排序后
的结果再产生 R,这样就不会乱了。
语句如下:

select * from
(select rownum r,t.* from
(select * from T_ACCOUNT order by usenum desc) t
where rownum<=20 )
where r>10;

字符函数

函数 说明
ASCII 返回对应字符的十进制值
CHR CHR 给出十进制返回字符
CONCAT 拼接两个字符串,与 ||相同
INITCAT 将字符串的第一个字母变为大写
INSTR 找出某个字符串的位置
INSTRB 找出某个字符串的位置和字节数
LENGTH 以字符给出字符串的长度
LENGTHB 以字节给出字符串的长度
LOWER 将字符串转换成小写
LPAD 使用指定的字符在字符的左边填充
LTRIM 在左边裁剪掉指定的字符
RPAD 使用指定的字符在字符的右边填充
RTRIM 在右边裁剪掉指定的字符
REPLACE 执行字符串搜索和替换
SUBSTR 取字符串的子串
SUBSTRB 取字符串的子串(以字节)
SOUNDEX 返回一个同音字符串
TRANSLATE 执行字符串搜索和替换
TRIM 裁剪掉前面或后面的字符串
UPPER 将字符串变为大写
常用字符函数讲解:
(1)求字符串长度 LENGTH
select length('abcd') 长度 from dual;

在这里插入图片描述
(2)求字符串的子串 SUBSTR

select substr('abcd',2,2) from dual;

在这里插入图片描述
(3)字符串拼接 CONCAT

select concat('abc','d') from dual;

在这里插入图片描述
我们也可以用|| 对字符串进行拼接

select 'abc'||'d' from dual;

在这里插入图片描述
查询结果同上。

数值函数

函数 说明
ABS(value) 绝对值
CEIL(value) 大于或等于 value 的最小整数
COS(value) 余弦
COSH(value) 反余弦
EXP(value) e 的 value 次幂
FLOOR(value) 小于或等于 value 的最大整数
LN(value) value 的自然对数
LOG(value) value 的以 10 为底的对数
MOD(value,divisor) 求模
POWER(value,exponent) value 的 exponent 次幂
ROUND(value,precision) 按 precision 精度 4 舍 5 入
SIGN(value) value 为正返回 1;为负返回-1;为 0 返回0
sin(value) 余弦
SINH(value) 反余弦
SQRT(value) value 的平方根
TAN(value) 正切
TANH(value) 反正切
TRUNC(value,按 precision) 按照 precision 截取 value
VSIZE(value) 返回 value 在 ORACLE 的存储空间大小

(1)四舍五入函数 ROUND

select round(100.567) from dual;

在这里插入图片描述

select round(100.567,2) from dual;

在这里插入图片描述
(2)截取函数 TRUNC

select trunc(100.567) from dual;

在这里插入图片描述

select trunc(100.567,2) from dual;

在这里插入图片描述
(3)取模 MOD

select mod(10,3) from dual;

在这里插入图片描述

日期函数

函数 描述
ADD_MONTHS 在日期 date 上增加 count 个月
GREATEST(date1,date2,. . .) 从日期列表中选出最晚的日期
LAST_DAY( date ) 返回日期 date 所在月的最后一天
LEAST( date1, date2, . . .) 从日期列表中选出最早的日期
MONTHS_BETWEEN(date2, date1) 给出 Date2 - date1 的月数(可以是小数)
NEXT_DAY( date,’day’) 给出日期 date 之后下一天的日期,这里的day 为星期,如: MONDAY,Tuesday 等。
NEW_TIME(date,’this’,’other’) 给出在 this 时区=Other 时区的日期和时间
ROUND(date,’format’) 未指定 format 时,如果日期中的时间在中午之前,则将日期中的时间截断为 12 A.M.(午夜,一天的开始),否则进到第二天。时间截断为 12 A.M.(午夜,一天的开始), 否则进到第二天。
TRUNC(date,’format’) 未指定 format 时,将日期截为 12 A.M.( 午夜,一天的开始)

我们用 sysdate 这个系统变量来获取当前日期和时间

select sysdate from dual;

在这里插入图片描述
(1)加月函数 ADD_MONTHS :在当前日期基础上加指定的月

select add_months(sysdate,2) from dual;

在这里插入图片描述
(2)求所在月最后一天 LAST_DAY

select last_day(sysdate) from dual;

在这里插入图片描述
(3)日期截取 TRUNC

select TRUNC(sysdate) from dual;

在这里插入图片描述

-- 按年度截取
select TRUNC(sysdate,'yyyy') from dual;

在这里插入图片描述

select TRUNC(sysdate,'mm') from dual;

转换函数

函数 描述
CHARTOROWID 将 字符转换到 rowid 类型
CONVERT 转换一个字符节到另外一个字符节
HEXTORAW 转换十六进制到 raw 类型
RAWTOHEX 转换 raw 到十六进制
ROWIDTOCHAR 转换 ROWID 到字符
TO_CHAR 转换日期格式到字符串
TO_DATE 按照指定的格式将字符串转换到日期型
TO_MULTIBYTE 把单字节字符转换到多字节
TO_NUMBER 将数字字串转换到数字
TO_SINGLE_BYTE 转换多字节到单字节

(1)数字转字符串 TO_CHAR

select TO_CHAR(1024) from dual;

在这里插入图片描述
(2)日期转字符串 TO_CHAR

select TO_CHAR(sysdate,'yyyy-mm-dd') from dual;

在这里插入图片描述

select TO_CHAR(sysdate,'yyyy-mm-dd hh:mi:ss')日期 from dual;

在这里插入图片描述
字符串转日期 TO_DATE

select TO_DATE('2017-01-01','yyyy-mm-dd') 日期 from dual;

在这里插入图片描述
(4)字符串转数字 TO_NUMBER

select to_number('100') from dual;

在这里插入图片描述

其它函数

(1)空值处理函数 NVL
用法:
NVL(检测的值,如果为 null 的值);

select NVL(NULL,0) from dual;

在这里插入图片描述
显示价格表中业主类型 ID 为 1 的价格记录,如果上限值为NULL,则显示9999999

select PRICE,MINNUM,NVL(MAXNUM,9999999)
from T_PRICETABLE where OWNERTYPEID=1;

在这里插入图片描述
(2)空值处理函数 NVL2
用法:
NVL2(检测的值,如果不为 null 的值,如果为 null 的值);
需求:显示价格表中业主类型 ID 为 1 的价格记录,如果上限值为NULL,显示“不限”

select PRICE, MINNUM, NVL2(MAXNUM, to_char(MAXNUM), '不限')
  from T_PRICETABLE
 where OWNERTYPEID = 1;

在这里插入图片描述
(3)条件取值 decode
语法:
decode(条件,值 1,翻译值 1,值 2,翻译值 2,…值 n,翻译值n,缺省值)
【功能】根据条件返回相应值

需求:显示下列信息(不要关联查询业主类型表,直接判断1 2 3 的值)

select name,
       decode(ownertypeid, 1, ' 居民', 2, ' 行政事业单位', 3, '商业') as 类型
  from T_OWNERS;

在这里插入图片描述
上边的语句也可以用 case when then 语句来实现

select name,
       (case ownertypeid
         when 1 then
          '居民'
         when 2 then
          '行政事业单位'
         when 3 then
          '商业'
         else
          '其它'
       end)类型
  from T_OWNERS;

在这里插入图片描述
还有另外一种写法:

select name,(case
when ownertypeid= 1 then '居民'
when ownertypeid= 2 then '行政事业'
when ownertypeid= 3 then '商业'
end )类型 from T_OWNERS;

在这里插入图片描述

行列转换

需求:按月份统计 2012 年各个地区的水费

select (select name from T_AREA where id = areaid) 区域,
       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 = '2012'
 group by areaid;

在这里插入图片描述
需求:按季度统计 2012 年各个地区的水费

select (select name from T_AREA where id= areaid )区域,
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='2012' group by areaid;

在这里插入图片描述

分析函数

以下三个分析函数可以用于排名使用。
下图为三种排名方式的举例
在这里插入图片描述
(1) RANK 相同的值排名相同,排名跳跃
需求:对 T_ACCOUNT 表的 usenum 字段进行排序,相同的值排名相同,排名跳跃
rank() over()排序

-- 分析函数
-- 值相同,排名相同,序号跳跃
select rank() over(order by usenum desc ),usenum from T_ACCOUNT;

在这里插入图片描述
(2) DENSE_RANK 相同的值排名相同,排名连续需求:对 T_ACCOUNT 表的 usenum 字段进行排序,相同的值排名相同,排名连续

-- 值相同,排名相同,序号连续
select dense_rank() over(order by usenum desc) 排名,t.usenum from t_account t;

在这里插入图片描述
(3) ROW_NUMBER 返回连续的排名,无论值是否相等需求:对 T_ACCOUNT 表的 usenum 字段进行排序,返回连续的排名,无论值是否相等

-- 序号连续,不管值是否相同
select row_number() over(order by usenum desc) 排名,t.usenum from t_account t;

在这里插入图片描述
用 row_number()分析函数实现的分页查询相对三层嵌套子查询要简单的多:

select * from
(select row_number() over(order by usenum desc )
rownumber,usenum from T_ACCOUNT)
where rownumber>10 

在这里插入图片描述

集合运算

什么是集合运算

集合运算,集合运算就是将两个或者多个结果集组合成为一个结果集。集合运算包括:
UNION ALL(并集),返回各个查询的所有记录,包括重复记录。
UNION(并集),返回各个查询的所有记录,不包括重复记录。
INTERSECT(交集),返回两个查询共有的记录。
MINUS(差集),返回第一个查询检索出的记录减去第二个查询检索出的记录之后剩余的记录。
在这里插入图片描述

并集运算

在这里插入图片描述
UNION ALL 不去掉重复记录

-- 集合运算
-- 包括重复记录
select * from t_owners where id<=7
union all
select * from t_owners where id>=5;

在这里插入图片描述
UNION 去掉重复记录

-- 集合运算
-- 不包括重复运算
select * from t_owners where id<=7
union
select * from t_owners where id>=5;

在这里插入图片描述

交集运算

在这里插入图片描述

-- 交集(两个结果集的重复部分)
select * from t_owners where id<=7
intersect
select * from t_owners where id>=5;

在这里插入图片描述

差集运算

在这里插入图片描述

-- 差集
select * from t_owners where id<=7
minus
select * from t_owners where id>=5;

在这里插入图片描述

差集分页

如果我们用 minus 运算符来实现分页,语句如下:

select rownum,t.* from T_ACCOUNT t where rownum<=20
minus
select rownum,t.* from T_ACCOUNT t where rownum<=10;

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Java_Fly1/article/details/124956885