【数据库】Oracle中的复杂数据处理

在介绍了Oracle中的基本数据类型及相应的处理函数后,本章将介绍Oracle中较为复杂的数据处理。

接下来,本文将介绍:

1、利用聚合函数来统计数据;

2、常用技巧;

3、oracle中的基本运算;

4、oracle特殊判式;

5、oracle中的分析与窗口函数


1. 利用聚合函数统计数据

前面几篇博客介绍的,都有一个共同的特点:均针对单一数据。

而聚合函数则是针对多个数据获得统计结果。使用聚合函数的场景大多为表中的数据,接下来的所有示例均基于表employees,其数据结构及内容如下所示。

SQL>select * from employees


表employees中存储了员工的基本信息,有员工ID、员工姓名、员工职位、员工年龄、员工家庭住址。


1.1 求最大值----max()函数

max()函数可以用于获得一组数据中的最大值,这里的“一组数据”通常为表中某列的所有值,max()函数可以应用的数据类型包括数值型和字符型。

(1)max()函数应用于数值型

max()函数应用于数值型时,是按照数值的大小顺序来获得最大值。

例子:为了获得员工的最大年龄可以利用如下所示的SQL语句

SQL>select max(employee_age) max_age from employees;

------

37

from employees提供了表employees中的所有记录作为数据源;max(employee_age)中的employee_age为数据列,该列的所有数据组成了max()函数的参数,max()函数则统计该组数据中的最大值。

max()函数的返回值是一个统计值,与数据表中的元数据并没有一一对应的关系。例如:表employees中可能存储了多个37岁的员工信息,而max()函数的返回值只是一个统计值。


(2)max()函数应用于字符型

max()函数不仅可以应用于数值型,还可以应用于字符型。当应用于字符型时,oracle会依照字母表由前到后的顺序进行排序。

例子:在表employees中,列employee_name为字符型,可以利用max()函数来获得去最大值。

SQL>select max(employee_name ) max_name from employees;

--------

钟小平


(3)max()函数应用于日期型

日期型的实质也是数值型,因此,max()函数应用于日期型与数值型具有完全相同的效果-----获得最晚日期。


1.2 求最小值-----min()函数

与max()函数相反,min()函数可以获得最小值。min()函数同样可应用于数值型、字符型和日期型。


1.3 求平均值-----avg()函数

avg()函数用于获得一组数据的平均值,该函数只能应用于数值型。

avg()函数的返回值是一个number型。


1.4求和----sum()函数

sum()函数用于获得一组数据的和。该函数同样只能应用于数值型。

例子:为了获得employees中所有员工年龄之和,可以利用如下SQL语句。

SQL.>select sum(employee_age ) sum_age from employees;


1.5 统计记录数-----count()函数

count()函数用于统计记录数目。该函数的常见使用场景有3种。

(1)统计单列

对于统计单列来说,列名作为count()函数的参数,当列值不为空时,将计数1;否则,将计数0。


(2)统计所有列

当表的所有列被作为count()函数的参数,即count(*)进行统计时,即使所有列值均为空,oracle仍将进行计数。

select count(*) from employees;


(3)利用count(1)进行统计

对于count()函数来说,还可以利用count(1)的形式进行统计。count(1)与count(*)返回的值相同,对每条记录都计数1.

SQL>select count(1) from employee;


2、oracle中的常用技巧

除了针对基本数据类型的各种函数之外,oracle还提供了一些其他技巧性函数。比如:

多值判断---decode()函数、为空值重新赋值---nvl()函数、结果集的行号----rownum()函数、强制转换数据类型-----cast()函数

2.1 多值判断-----decode()函数

在oracle中,可以利用if else和case语句进行判断,当然还有decode()函数处理该问题,从而减少了代码量,并增强了SQL语句的可读性。

decode()函数的使用语法如下:

decode(表达式,比较值1,结果值1,比较值2,结果值2,....,默认值)

decode()函数的处理过程类似于解码过程,第一个参数表达式往往为变量或者数据表中的列;其后的参数总是以“比较值---结果值”对的形式出现,表达式的值与“比较值”进行比较,如果二者相等,则返回相应的“结果值”;若果所有比较都不成功,那么将返回默认值。

例子:在表employees所存储的数据表中,列employee_position标识了员工的职位,现需要对员工进行分类:职位是工程师的员工规划技术部,其他员工划为行政管理部。那么可以利用decode()函数来实现这一用法。


decode(sign(instr(employee_position,'工程师')), 1, '技术部', '行政管理部')中 sign(instr(employee_position,'工程师'))用于获得列employee_position中字符串“工程师”的位置,并判断其正负性;1,‘技术部’是第一个“比较值---结果值”键值对,表示当员工为工程师时,返回字符串“技术部”;最后一个参数“行政管理部”为默认值。


2.2 空值处理-----nvl()函数

数据库中的数据难免出现空值,但是对于用户来说,空值并不够友好。用户更愿意获得有意义的数据,nvl()函数可以判断表达式的值是否为空。如果为空,则可以返回新值;若不为空,则返回原值。其使用语法如下所示:

nvl(表达式,新值/表达式)

nvl()函数首先判断第一个表达式参数的值是否为空;如果为空,则返回第二个参数的的值;如果不为空,则返回第一个参数表达式的值。

例子:表employees和表salary分别存储了员工及员工工资信息,可以通过分组获得员工及员工总额信息。

nvl(sum(salary), 0 ) 用于判断员工的工资总额是否为空,如果为空则返回0,因此记录1--5的工资总额仍然保持原值,而记录6--8的工资总额被置为0.


2.3 结果集的行号----rownum()函数

rownum()函数可以返回结果集的行号,对于select语句,没捕获一条记录,rownum()函数的返回值将累加1,否则,rownum()的返回值保持不变。

(1)利用rownum为搜寻结果添加一列

例子:rownum的最简单应用场景是为搜寻结果添加一列,如下所示。

SQL>select e.employee_id,  e.employee_name, rownum from emplyees e;

select e.employee_id,  e.employee_name, rownum from emplyees e用于遍历表employees,并捕获每条记录中的employee_id和employee_name列;每捕获一条记录,rownum的返回值将累加1,因此,rownum依次返回1--8的值。


(2)rownum与order by子句。

对表中数据排序,然后获得排名在某个范围之内的记录是一种常见需求。例如,要求获得表employees中、按员工姓名排序前3位的员工信息。一种常见的思路为综合利用rownum与order by子句排序并增加过滤条件----rownum小于等于3.

SQL>select e.employee_id, employee_name, rownum from employees e where rownum <= 3 order by e.employee_name;

EMPLOYEE_ID    EMPLOYEE_NAME    ROWNUM

-------------------       -------------------------     -----------

3                                  刘俊                               3 

1                                  王晓                              1

2                                   钟小平                          2

where rownum<=3用于限制rownum小于等于3的记录;order by e.employee_name用于对表employees中的记录按照employee_name列进行排序。

从上面的查询结果可以看出,并不是预期的效果。原因在于where条件先于order by子句执行。也就是说,Oracle总是先利用where条件过滤搜寻记录,最后才利用order by进行排序。而rownum的返回值用于where条件判断,这造成了所有rownum执行完毕之后在再执行排序操作。

该需求的正确解决方式为,首先利用内嵌式图获得排序之后的结果,然后对内嵌视图所代表的结果集使用rownum()函数,SQL语句如下所示:

SQL>select t.*, rownum from (

select e.employee_id, employee_name from employees e order by e.employee_name)  t where rownum<=3

EMPLOYEE_ID   EMPLOYEE_NAME     ROWNUM

--------------------    -------------------------     ---------------

7                                 李四                                 1

3                                 刘俊                                  2

4                                  王龙                                 3

内嵌视图 t  的定义为select e.employee_id, employee_name from employees e order by e.employee_name.该内嵌视图所代表的结果集如下:

EMPLOYEE_ID                EMPLOYEE_NAME

---------------------                ---------------------------

7                                                   李四

3                                                    刘俊

4                                                   王龙

8                                                    王五

1                                                    王晓

6                                                    张三

5                                                    钟文

2                                                    钟小平

对该结果集来说,rownum<=3将返回前3条记录,即为:

EMPLOYEE_ID           EMPLOYEE_NAME

-------------------             ----------------------------

7                                        李四

3                                        刘俊

4                                        王龙

因此,对于rownum()函数的使用来说,首先要观察rownum()函数出现在查询语句的哪个子句中,而子句的执行时机往往决定rownum()函数的返回值。


(3)rownum与比较运算符“=‘

rownum()函数常常出现在查询条件中,SO,rownum()函数与比较运算符“=”的结合使用。

例子:现需要获得employees中,行号为1的员工信息,最容易想到的SQL语句如下:

SQL>select e.employee_id, e.employee_name, rownum from employees e where rownum =1;

分析查询结果可知,利用rownum=1可以获得预期的结果,但是,利用该方法无法成功获得行号为4的员工信息。

【分析】这是因为rownum总是从1开始,如果不能获得rownum为1的记录,那么rownum的返回值永远无法达到大于1的数字。可以通过分析该SQL语句的执行过程解释查询失败的原因。

select e.employee_id, e.employee_name, rownum from employees e 用于自表employees中获取记录;where rownum=4则指定了过滤条件;当Oracle遍历至表employees的第一条记录时,rownum为1,但是where rownum=4为假,那么该记录不在捕获范围;当遍历至表employees的第二条记录时,因为捕获记录为0,rownum仍然返回 1,;以此类推,无论Oracle遍历多少条记录,rownum总是为1,也永远无法满足rownum=4的条件。

事实上,单纯利用rownum=n作为查询语句的过滤条件,当n大于1室,返回的查询结果永远为空。此处,仍然可以通过内嵌视图来解决该问题。


(4)rownum与比较运算符“>”

例子:与比较运算符“=”类似,如果对rownum使用了对于运算,而比较值又大于等于 1 时,Oracle同样返回空的结果集。

如果,当rownum>n中的  n 小于1,那么查询语句将返回所有记录。


2.4 强制转换数据类型-----cast()函数

Oracle中的cast()函数可以强制转换列或变量的数据类型。其语法如下所示:

cast( 元数据  as   新的数据类型 )


3、Oracle中的运算

Oracle中的常用运算包括数学运算、逻辑运算、比较运算和按位运算。


4、Oracle中的特殊判式

Oracle进行条件判断时,最常见的操作符为“=’。除此之外,oracle还提供了若干特殊判式进行逻辑判断。这些判式包括:

between-----范围测试;in-----集合成员测试;like----模糊匹配;is null-----空值判断;exits-----存在性判断;all、some、any----数量判断。

4.1 between-----范围测试

between可以用于判断列或表达式的值是否处于某个范围之内。其使用语法如下:

between x and y

其中,x和y限定了范围的临界值。


4.2 in -------集合成员测试

in判式用于判断某个列或表达式的值是否处于某个结合之内


4.3 like-----模糊匹配

用户在查询数据时,往往并不能提供精确的匹配条件。例如:用户试图通过公司名称查询记录时,并不能提供精确的公司全称;又如,用户可能希望获得某位员工的信息,而只能确定员工的姓氏。这些情况下,即可使用模糊查询,oracle中提供了like判式实现模糊匹配。

(1)、匹配任意字符串----“%”

对于like判式,最常用的通配符为“%”,该通配符可用于匹配任意长度的任意字符。

比如:'刘%',指定查询条件为该列的值以“刘”为开头,后面跟任意长度的任意字符,因此将返回所有刘姓员工的姓名。


(2)、匹配单个字符-----“_”

对于like判式,另外一个常用通配符为“_”。该通配符可用于匹配任意的单个字符。

例子:'刘_',指的是刘后面只能跟一个字符。。

当然,多个通配符“_”可以同时使用,比如:'刘__',刘后面跟着两个“_”。


(3)原义字符

在like判式中,通配符“%”和“_” 有着特殊的意义。但是有时候用户希望判断标准中出现了这两个字符,那么将需要二者的原义字符。

例子:对于一个字符串,百分比“20%”,用户希望判断是否该字符串以“%”结尾,直接在判式中使用“%”无法达到预期效果。

因此,需要用到"\";   like ‘%\%’中的第一个%,表示通配符;而后面的表示原义字符。  


4.4 is null  -----空值判断

oracle中不能使用“=”判断一个列或者表达式的值是否为空 ,而是利用特殊判式 is null.

当然,is null判式的对立面是is not null,为了获得所有列值均完整无缺的记录,相应的SQL语句如下所示。

SQL> select * from employees 

where employee_id is not null

and employee_name in not null

and ....

............

利用is not null对表中的所有列进行判断,可以获得所有列值均不为空的记录。


4.5 exits---存在性判断

exits判式可以用于判断记录的存在性,exits判式的操作对象是结果集,当结果集汇中记录大于0时,将返回为真,否则,将返回为假。



转载于:https://www.cnblogs.com/iamliuxin/p/5617800.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值