oracle分析函数
1. 引言
最近心血来潮去参加了一个PL/SQL工程师的面试,期间被问到了Oracle分析函数,PL/SQL开发并非我的老本行,在之前的工作中,也很少使用分析函数,原因之一是对数据库移植问题的考虑;其二是很少遇到非用分析函数不可的情况;其三是分析函数的语法相对复杂,令人缺乏兴趣。这几天看了一些入门内容,发现它们还是很强大的,唯一的遗憾是目前身边没有真实的应用场景,所以这里举的例子看起来难免有点纸上谈兵的感觉。
2. 分析函数(Analyticfunction)与聚合函数(Aggregate function)
我们先从 “ORA-00979: not a GROUPBY expression”说起,相信大家在开始使用SQL的过程中都遇到过这个错误,比如你写了下面这样的SQL:
SELECT title, corp, COUNT(*) cnt
FROM film
GROUP BY corp
ORDER BY corp;
ORA-00979错误表明,SELECT子句中出现的字段,要么包含于GROUP BY子句,要么作为聚合函数(上面的COUNT)的输入,除此之外不能包含其它字段。我们可以修改上面的SQL使它可以正常运行:
SELECT corp, COUNT(*) af
FROM film
GROUP BY corp
ORDER BY corp;
这就引出了聚合函数的一个主要特征,聚合之后,同组只保留下一条数据,由上图可知表中由“20th CenturyFox”公司出品的影片共有7部,最终记录是一条。
这符合某些统计需求,然而有时候,我们并不希望聚合函数中的这种“合并”操作,尤其是我们常常希望在SELECT子句出现未参与统计的字段,此时我们便可以使用分析函数。对于表中的每一行记录,分析函数都能返回一个统计值,下面我们来看一个具体的实例:
SELECT title,year,corp,
COUNT(*) OVER (PARTITION BY corp) af
FROM film;
注:PARTITION BY不仅导致分区(类似于GROUP BY),而且分区之间是排序好的,也算是它的一个“副作用”。
3. 基本语法
function_name(arg1,arg2,...) OVER(
clause>)
其中子句会在下面的例子中穿插提到,子句则会在最后一节进行解释。
另外,还需要提到的一点是,在有分析函数参与的SQL语句中,执行流程依次是:
1)JOIN, WHERE, GROUP BY, HAVING
2)创建分区(通常通过PARTITION BY),而后分析函数将作用于分区中的每一行
3)主语句中ORDER BY(这个我们以前就知道,主语句的ORDER BY总是最后执行)。
4. AVG,SUM, MAX, MIN, COUNT
这些大家熟知的聚合函数,同样可作为分析函数使用,当然要符合第3节中给出的分析函数的语法,下面我们来看几个实例:
SELECT title,corp,year,box_office,
ROUND(AVG(box_office) OVER (PARTITION BY corp)) af
FROM film;
让我们看看在OVER内应用ORDER BY之后的情形:
SELECT title,year,corp,
COUNT(*) OVER (PARTITION BY corp ORDER BY year) af
FROM film;
这个结果容易让人非常困惑,实际上OVER内的ORDER BY子句导致了分区(PARTITION)内的数据进行了逐步累加。通常,这种“累加”始于排序后该分区的第一条记录,结束于当前记录。当排序列出现相同值(比如上面的两个1997、两个2009),累加则结束于相同记录的最后一条。
让我们再来看一个例子:
#p#分页标题#e#SELECT title,corp,year,box_office,
MAX(box_office) OVER (PARTITION BY corp ORDER BY year) af
FROM film;
5. RANK,DENSE_RANK, ROW_NUMBER
代码SELECT title, corp, year,
RANK() OVER (PARTITION BY corp ORDER BY year) r,
DENSE_RANK() OVER (PARTITION BY corp ORDER BY year) dr,
ROW_NUMBER() OVER (PARTITION BY corp ORDER BY year) rn
FROM film;
RANK,DENSE_RANK, ROW_NUMBER具有类似的行为,只有当排序列包含重复值时,它们的区别才能体现出来。注意上图中红色标识部分,对于相同的年份1997,RANK, DENSE_RANK都返回相同的值,不同的时,DENSE_RANK采用密集编号,两个1之后接着的编号是2。对于ROW_NUMBER,则总是产生连续的编号。
利用这几个函数的特性,可以相对简单地实现TOP N的查询,例如查询表中各电影公司年份最早的电影:
SELECT * FROM (
SELECT title,corp,year,
RANK() OVER (PARTITION BY corp ORDER BY year) r
FROM film
) t
WHERE t.r=1;
6. LEAD,LAG
基本语法:
LEAD(,, ) OVER ()
LAG(,, ) OVER ()
:通常是字段名。
:表示相对于当前行的偏移幅度(对LEAD来说是向后偏移,对LAG来说则是向前),正整数,默认为1。
:当偏移幅度超出该分区(PARTITION)的范围时返回的值。
SELECT title,corp,year,box_office,
LEAD(box_office,1,-9999) OVER (PARTITION BY corp ORDER BY box_office) af1,
LAG(box_office,1,-9999) OVER (PARTITION BY corp ORDER BY box_office) af2
FROM film;
我们先来分析LEAD函数的结果,即上图中的AF1字段,对于同一行分区内,AF1字段第N行的值= 原BOX_OFFICE第N+1行的值,参见红色标识部分。为什么是N+1呢?实际这取决到我们在SQL语句中指定的offset,我们上面指定的是1。
如果偏移之后超过了分区的范围,则返回函数中指定的default值,这里我们指定的是-9999。
LAG与LEAD类似,只不过它的偏移是向前的,这点与LEAD相反。
7. FIRST_VALUE,LAST_VALUE FIRST_VALUE返回各分区内指定排序后的第一条记录的值,LAST_VALUE则返回最后一条记录的值。
SELECT title,corp,year,box_office,
box_office-(FIRST_VALUE(box_office) OVER (PARTITION BY corp ORDER BY box_office)) af
FROM film;
8. #p#分页标题#e#Window子句
我们在第3节提到了分析函数中还有一个window clause,该子句为分析函数指定统计“窗口”。在前面的例子中,大多数的统计“窗口”都是整个分区(PARTITION),也就是说每个统计结果值都是基于相应分区内的所有数据计算而得。使用Window子句则可以将统计“窗口”进一步缩小,我们看一个例子:
SELECT title,corp,year,box_office,
MAX(box_office) OVER (PARTITION BY corp ORDER BY year ROWS BETWEEN 2 PRECEDING AND 1 FOLLOWING) af
FROM film;
由于分析函数中给定的窗口是ROWS BETWEEN 2 PRECEDINGAND 1 FOLLOWING,基本上我们可以按字面意思理解“2 Preceding”跟“1 Following”,这表示“窗口”始于当前行之前两行,终于当前行之后一行,“窗口”大小共4行,所以我们看最后一列中红色标识的1840000000是由第1行到第4行中求得的MAX值;而最后一列中蓝色标识的920000000则是由第2行到第5行中求得的MAX值。
回过来看Window子句的具体语法:
ROWSBETWEEN AND
其中与 可能是以下形式:
(1)1, 2, ..., N PRECEDING|FOLLOWING
(2)UNBOUNDED PRECEDING|FOLLOWING
(3)CURRENT ROW
还存在一种更简单的语法:
ROWS1, 2, ..., N PRECEDING 或ROWSUNBOUNDED PRECEDING
此时,统计“窗口”默认结束于当前行。
再来看一个综合例子:
代码SELECT title,corp,year,box_office,
MAX(box_office) OVER (PARTITION BY corp ORDER BY year ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) af1,
MAX(box_office) OVER (PARTITION BY corp ORDER BY year ROWS BETWEEN 2 PRECEDING AND UNBOUNDED FOLLOWING) af2,
ORACLE统计函数大全
【一】、Oracle常用的统计函数
Avg(x):求一组行中列x值的平均值
count(x):求一组行中列x值的非空行数
count(*):求一组行的总行数
max(x):求一组行中列x值的最大值
min(x):求一组行中列x值的最小值
stddev(x):求一组行中列x值的标准差
sum(x):求一组行中列x值的总和
variance(x):求一组行中列x值的方差
【二】、group by与统计函数
使用上面介绍的函数时可以使用也可以不使用group by ,但在使用group by时,未在group by部分用到的列在select
部分出现时必须使用统计函数,如按角色统计平均年龄
Select user_name,avg(age) from users
Group by role_id; ×
Select count(user_name),avg(age) from users
Group by role_id√
【三】、用having字句规定统计条件
having 子句的作用类似于where子句,只不过where 子句针对单个行,而having子句针对的是统计结果,一般和统计
的函数搭配使用。Having子句后必须为前面select后面的子部分,或是group by 后面的字段
select count(uer_name),avg(age) from users group by role_id having role_id>20; ×
select count(uer_name),avg(age) from users group by role_id having avg(age)>20; √
【四】其他oracle常用函数
Decode(column1,value1,output1,value2,output2,…..)
如果column1 有一个值为value1那么将会用output1 来代替当前值,如果column1 的值为value2 那么就用OUTPUT2 来
Oracle分组函数之ROLLUP的基本用法
Oracle分组函数之ROLLUP的基本⽤法
rollup函数
本博客简单介绍⼀下oracle分组函数之rollup的⽤法,rollup函数常⽤于分组统计,也是属于oracle分析函数的⼀种
环境准备
create table dept as select * from scott.dept;
create table emp as select * from scott.emp;
业务场景:求各部门的⼯资总和及其所有部门的⼯资总和
这⾥可以⽤union来做,先按部门统计⼯资之和,然后在统计全部部门的⼯资之和
select a.dname, sum(b.sal)
from scott.dept a, scott.emp b
where a.deptno = b.deptno
group by a.dname
union all
select null, sum(b.sal)
from scott.dept a, scott.emp b
where a.deptno = b.deptno;
上⾯是⽤union来做,然后⽤rollup来做,语法更简单,⽽且性能更好
select a.dname, sum(b.sal)
from scott.dept a, scott.emp b
where a.deptno = b.deptno group by rollup(a.dname);
业务场景:基于上⾯的统计,再加需求,现在要看看每个部门岗位对应的⼯资之和
select a.dname, b.job, sum(b.sal)
from scott.dept a, scott.emp b
where a.deptno = b.deptno
group by a.dname, b.job
union all//各部门的⼯资之和
select a.dname, null, sum(b.sal)
from scott.dept a, scott.emp b
oracle 百分比函数
Oracle 百分比函数是在 Oracle 数据库系统中大量使用的一种函数。它可以用来计算某个值在整个结果集中的百分比。例如,计算某个城市的人口在全国总人口中的百分比。
Oracle 提供了一种叫做PERCENT_RANK的函数,可以用来计算百分比。它的语法如下:PERCENT_RANK(expression1, expression2, expression3)。其中,expression1表示要计算百分比的值,expression2表示结果集中的所有值,expression3表示结果集中的记录数。
另外,Oracle 还提供了一种叫做RANK的函数,它的功能也是计算百分比,但与PERCENT_RANK函数不同的是,它会根据结果集中的值的大小来计算每个值的百分比。它的语法如下:RANK(expression1, expression2)。其中,expression1表示要计算百分比的值,expression2表示结果集中的所有值。
此外,Oracle 还提供了一种叫做DENSE_RANK的函数,它可以用来计算百分比,但与RANK函数不同的是,它会根据结果集中的值的大小来计算每个值的百分比,并且它会忽略结果集中值相等的情况。它的语法如下:DENSE_RANK(expression1, expression2)。其中,expression1表示要计算百分比的值,expression2表示结果集中的所有值。
Oracle 百分比函数可以大大提高计算效率,可以帮助我们更加快速准确地统计出数据的百分比值,从而更方便地分析数据。此外,这些函数还可以用来实现类似分组统计的功能,比如统计某个值在某个分组中的百分比。
oracle的count函数
Oracle的COUNT函数
介绍
在Oracle数据库中,COUNT函数是一种聚合函数,用于查询满足指定条件的行数。COUNT函数的语法为:
COUNT(expr)
其中,expr是要统计的列或表达式。COUNT函数会返回该列或表达式的非空值的数量。
COUNT函数可以与其他数据库函数(如SUM、MAX、MIN等)一起使用,也可以与GROUP BY子句一起使用以对结果分组。
本文将深入探讨Oracle的COUNT函数,包括使用方法、常见应用场景等。
使用方法
COUNT函数可以用于不同的场景和用途,具体取决于expr参数的使用方式。下面是一些常见的使用方法:
统计表中的行数
SELECT COUNT(*) FROM table_name;
上述语句将返回表table_name中的总行数。COUNT函数的参数使用通配符*,表示统计所有行。
统计某列的非空值数量
SELECT COUNT(column_name) FROM table_name;
上述语句将返回表table_name中列column_name的非空值数量。COUNT函数的参数为具体的列名。
结合条件统计行数
SELECT COUNT(*) FROM table_name WHERE condition; 上述语句将返回表table_name中满足条件condition的行数。可以根据实际需要对条件进行组合和筛选。
常见应用场景
COUNT函数在数据分析和报表生成等场景中具有广泛的应用。以下是一些常见的应用场景:
统计订单数量
SELECT COUNT(*) FROM orders;
通过COUNT函数,可以轻松统计订单表中的订单数量。对于电商平台等需要分析销售数据的场景很有用。
筛选满足条件的行数
SELECT COUNT(*) FROM products WHERE price > 1000;
通过COUNT函数结合条件语句,可以筛选出满足特定条件的行数。例如,上述语句统计了价格大于1000的产品数量。
oracle 分组统计函数
oracle 分组统计函数
Oracle是一种流行的关系型数据库管理系统,具有强大的分组统计函数,可以帮助用户轻松实现数据分析和汇总。在本文中,我们将介绍几种常用的Oracle分组统计函数,并说明它们的用途和功能。
GROUP BY子句是SQL语句中用于对查询结果进行分组的重要部分。在Oracle中,可以结合使用GROUP BY子句和聚合函数来实现数据的分组统计。以下是几种常用的Oracle分组统计函数:
1. COUNT函数:COUNT函数用于统计查询结果集中行的数量。可以结合GROUP BY子句使用,以实现对分组数据的计数统计。例如,可以使用COUNT(*)来统计每个分组中的行数,或者使用COUNT(column_name)来统计指定列中非空值的数量。
2. SUM函数:SUM函数用于计算指定列的合计值。可以结合GROUP BY子句使用,以实现对分组数据的求和统计。例如,可以使用SUM(column_name)来计算每个分组中指定列的合计值。
3. AVG函数:AVG函数用于计算指定列的平均值。可以结合GROUP
BY子句使用,以实现对分组数据的平均值统计。例如,可以使用AVG(column_name)来计算每个分组中指定列的平均值。
4. MAX函数:MAX函数用于找出指定列的最大值。可以结合GROUP BY子句使用,以实现对分组数据的最大值统计。例如,可以使用MAX(column_name)来找出每个分组中指定列的最大值。
5. MIN函数:MIN函数用于找出指定列的最小值。可以结合GROUP
BY子句使用,以实现对分组数据的最小值统计。例如,可以使用MIN(column_name)来找出每个分组中指定列的最小值。
除了上述常用的分组统计函数外,Oracle还提供了其他一些函数,如STDDEV、VARIANCE等,用于计算标准差和方差等统计指标。这些函数可以帮助用户更全面地分析数据,发现数据的规律和趋势。
oracle的开窗函数
oracle的开窗函数
开窗函数指的是OVER(),和分析函数配合使⽤。
语法:OVER(PARTITION BY 分组字段 ORDER BY 排序字段 ROWS BETWEEN 排序字段范围值1 AND 排序字段范围值2)
语法说明:开窗函数为分析函数带有的,包含三个分析⼦句:1. 分组(PARTITION BY)。
2. 排序(ORDER BY)。
3. 窗⼝(ROWS)-- 指定范围。
ROWS 有多个范围值:
1. UNBOUNDED PRECEDING ⽆限/不限定 先前⾏。
2. N PRECEDING N个先前⾏(N为1则是1个先前⾏,2则是2个先前⾏,以此类推)。
3. UNBOUNDED FOLLOWING ⽆限/不限定 的跟随⾏。
4. N FOLLOWING N个跟随⾏(N为1则是1个跟随⾏,2则是2个跟随⾏,以此类推)。
5. CURRENT ROW 当前⾏。
⽰例1:SELECT
CCTI.CTR_TYPE_ID,
CCTI.ORDER_NUM,
,
WMSYS.WM_CONCAT() OVER
(PARTITION BY CCTI.CTR_TYPE_ID) CTR_TYPE_ITEM_STR
FROM T_CTRG_CTR_TYPE_ITEM CCTI;
结果1:
分析1:
区别于GROUP BY⼦句的只返回分组⾏的结果,开窗函数每⼀⾏都会返回⼀个结果。
⽰例1的写法相当于指定了ROWS范围从不限定先前⾏到不限定跟随⾏(默认):SELECT
CCTI.CTR_TYPE_ID,
CCTI.ORDER_NUM,
,
WMSYS.WM_CONCAT() OVER
(PARTITION BY CCTI.CTR_TYPE_ID ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) CTR_TYPE_ITEM_STR
oracle判断正负的函数
Oracle判断正负的函数
1. 引言
在计算机编程和数学中,判断一个数的正负是一个基本的操作。在Oracle数据库中,我们可以使用函数来判断一个数是正数、负数还是零。本文将详细介绍如何编写一个Oracle函数来完成这个任务。
2. Oracle内置函数
Oracle提供了一些内置函数用于数值操作,包括判断正负的函数。下面是两个常用的函数:
2.1. SIGN函数
SIGN函数用于判断一个数的正负,并返回对应的符号。当参数为负数时,函数返回-1;当参数为正数时,函数返回1;当参数为零时,函数返回0。
2.2. ABS函数
ABS函数用于返回一个数的绝对值。无论参数是正数还是负数,函数都会返回一个非负数。
3. 自定义Oracle函数
除了使用内置函数外,我们还可以自定义一个Oracle函数来判断一个数的正负。下面是一个示例函数的定义:
CREATE OR REPLACE FUNCTION check_sign(num IN NUMBER)
RETURN VARCHAR2
IS
result VARCHAR2(10);
BEGIN
IF num > 0 THEN
result := 'Positive';
ELSIF num < 0 THEN
result := 'Negative'; ELSE
result := 'Zero';
END IF;
RETURN result;
END;
/
上述函数接受一个NUMBER类型的参数num,并根据num的值返回对应的字符串。如果num大于0,则返回”Positive”;如果num小于0,则返回”Negative”;如果num等于0,则返回”Zero”。
4. 使用内置函数判断正负
在Oracle中,我们可以使用内置函数SIGN来判断一个数的正负。下面是一个使用SIGN函数的示例:
SELECT SIGN(10) AS result
ORACLE常用函数在GBASE中对应函数
函数类型oracle函数Gbase函数to_date(string,format)to_date(string,format)sysdatesysdate()或者now()add_months(date,number)add_months(date,number)sysdate+nadddate(sysdate(),n)last_day(date)last_day()month_between(date,date)timestampdiff(month,date,date)
trunc(sysdate,'day')adddate(curdate(),-weekday(curdate()))ascii(str)ascii(str)to_char()to_char()substr()substr()instr(str,substr)instr(str,substr)nvlnvlcase whencase whentrim(str)trim(str)ltrim(str)ltrim(str)rtrim(str)rtrim(str)to_number()to_number()rowidreplace(str,from_str,to_str)replace(str,from_str,to_str)concat()concat()repeat(str,count)repeat(str,count)lower(str)lower(str)upper(str)upper(str)length(str)length(str)lengthb(str)不支持abs(n)abs(n)ceil(n)ceil(n)floor(n)floor(n)mod(m,n)mod(m,n)trunctruncateroundroundsumsumcountcountavgavgmaxmaxminminvm_concat,listagggroup_concatrank()overrank()overdense_rank()overdense_rank()overrow_number()overrow_number()oversum()oversum()overavg()overavg()overcount()overcount()overmax()overmax()overmin()overmin()overlead()overlead()overlag()overlag()overtrunctrunc日期函数
oracle数学函数
oracle数学函数
Oracle数学函数是Oracle数据库中提供的一组函数,用于进行数学运算和处理数值数据。这些函数可以用于计算、转换和处理数值,使得数据处理更加灵活和高效。本文将介绍几个常用的Oracle数学函数,并详细说明其用法和功能。
1. ROUND函数
ROUND函数用于对数值进行四舍五入。它接受两个参数,第一个参数是要进行四舍五入的数值,第二个参数是要保留的小数位数。例如,ROUND(3.14159, 2)将返回3.14,表示将3.14159四舍五入到小数点后两位。
2. TRUNC函数
TRUNC函数用于截断数值,即将数值的小数部分截断掉。它接受两个参数,第一个参数是要进行截断的数值,第二个参数是要保留的小数位数。例如,TRUNC(3.14159, 2)将返回3.14,表示将3.14159截断到小数点后两位。
3. MOD函数
MOD函数用于计算两个数的余数。它接受两个参数,第一个参数是被除数,第二个参数是除数。例如,MOD(10, 3)将返回1,表示10除以3的余数为1。
4. POWER函数 POWER函数用于计算一个数的幂。它接受两个参数,第一个参数是底数,第二个参数是指数。例如,POWER(2, 3)将返回8,表示计算2的3次幂。
5. SQRT函数
SQRT函数用于计算一个数的平方根。它接受一个参数,即要计算平方根的数值。例如,SQRT(9)将返回3,表示计算9的平方根。
6. ABS函数
ABS函数用于计算一个数的绝对值。它接受一个参数,即要计算绝对值的数值。例如,ABS(-5)将返回5,表示计算-5的绝对值。
7. EXP函数
EXP函数用于计算以自然对数为底的指数幂。它接受一个参数,即要计算指数幂的数值。例如,EXP(1)将返回2.71828,表示计算e的1次幂。
8. LOG函数
LOG函数用于计算一个数的自然对数。它接受一个参数,即要计算自然对数的数值。例如,LOG(10)将返回2.30259,表示计算以e为底的对数。
oracle的count函数 2
oracle的count函数
Oracle的COUNT函数是用于统计某个列或表达式的非空行数。它可以在SELECT语句中使用,也可以用于GROUP BY子句中进行分组计数。COUNT函数有以下几种使用方式:
1. 统计表中所有行的数量:
COUNT(*)函数可以统计表中所有行的数量,包括空行和重复行。它的语法如下:
```sql
SELECT COUNT(*) FROM 表名;
```
要统计名为"employees"的表中所有行的数量,可以使用以下语句:
```sql
SELECT COUNT(*) FROM employees;
```
2. 统计某个列的非空值数量:
COUNT(column_name)函数可以统计某个列中非空值的数量。它的语法如下:
```sql
SELECT COUNT(column_name) FROM 表名; ```
要统计名为"employees"表中"salary"列非空值的数量,可以使用以下语句:
```sql
SELECT COUNT(salary) FROM employees;
```
3. 统计满足条件的行数:
COUNT函数还可以结合WHERE子句来统计满足条件的行数。它的语法如下:
```sql
SELECT COUNT(*) FROM 表名 WHERE 条件;
```
要统计名为"employees"表中工资大于5000美元的员工数量,可以使用以下语句:
```sql
SELECT COUNT(*) FROM employees WHERE salary > 5000;
```
4. 分组统计:
COUNT函数还可以与GROUP BY子句一起使用,用于分组统计。它的语法如下:
```sql SELECT column_name, COUNT(*) FROM 表名 GROUP BY
