客户从Oracle数据库迁移至KingbaseES数据库,应用中使用MEDIAN函数来求中位数。KingbaseES数据库中没有MEDIAN函数,但可以通过百分比函数来实现相应的功能。

MEDIAN 函数

MEDIAN是一个假设连续分布模型的逆分布函数。它采用一个数字或日期时间值,并返回中间值或插值,该值在值排序后将成为中间值。在计算中会忽略null。

以下是摘自Oracle官网说明

语法:
MEDIAN(expr) [ OVER ( [ query_partition_clause ] ) ] MEDIAN is an inverse distribution function that assumes a continuous distribution model. It takes a numeric or datetime value and returns the middle value or an interpolated value that would be the middle value once the values are sorted. Nulls are ignored in the calculation. The result of MEDIAN is computed by first ordering the rows. Using N as the number of rows in the group, Oracle calculates the row number (RN) of interest with the formula RN = (1 + (0.5*(N-1)). The final result of the aggregate function is computed by linear interpolation between the values from rows at row numbers CRN = CEILING(RN) and FRN = FLOOR(RN).
计算公式:
if (CRN = FRN = RN) then
(value of expression from row at RN)
else
(CRN - RN) * (value of expression for row at FRN) +
(RN - FRN) * (value of expression for row at CRN)

KingbaseES中有2个用于计算百分比的函数 PERCENTILE_CONT 和 PERCENTILE_DISC。

PERCENTILE_CONT 函数

PERCENTILE_CONT 是一种假定连续分布模型的逆分布函数。该函数具有一个百分比值和一个排序规范,并返回一个在有关排序规范的给定百分比值范围内的内插值。

PERCENTILE_CONT 在对值进行排序后计算值之间的线性内插。通过在聚合组中使用百分比值 (P) 和非 null 行数 (N),该函数会在根据排序规范对行进行排序后计算行号。根据公式 (RN) 计算此行号 RN = (1+ (P*(N-1))。聚合函数的最终结果通过行号 CRN = CEILING(RN) 和 FRN = FLOOR(RN) 的行中的值之间的线性内插计算。

最终结果将如下所示:

如果 (CRN = FRN = RN),则结果为 (value of expression from row at RN)

否则结果为 (CRN - RN) * (value of expression for row at FRN) + (RN - FRN) * (value of expression for row at CRN)

语法:
PERCENTILE_CONT ( percentile ) WITHIN GROUP (ORDER BY expr) OVER ( [ PARTITION BY expr_list ] ) 参数说明
percentile:介于 0 和 1 之间的数字常数。计算中将忽略 Null。
WITHIN GROUP ( ORDER BY expr) :指定用于排序和计算百分比的数字或日期/时间值。
OVER :指定窗口分区。
PARTITION BY expr 设置 OVER 子句中每个组的记录范围的可选参数。

PERCENTILE_DISC 函数

PERCENTILE_DISC 是一种假定离散分布模型的逆分布函数。该函数具有一个百分比值和一个排序规范,并返回给定集合中的元素。

对于给定的百分比值 P,PERCENTILE_DISC 在 ORDER BY 子句中对表达式的值进行排序,并返回带有大于或等于 P 的最小累积分布值(相对于同一排序规范)的值。

语法
PERCENTILE_DISC ( percentile ) WITHIN GROUP (ORDER BY expr) OVER ( [ PARTITION BY expr_list ] )
参数说明
percentile:介于 0 和 1 之间的数字常数。计算中将忽略 Null。
WITHIN GROUP ( ORDER BY expr) :指定用于排序和计算百分比的数字或日期/时间值。
OVER :指定窗口分区。
PARTITION BY expr 设置 OVER 子句中每个组的记录范围的可选参数。

注意:KingbaseES数据库在 V008R006C007B0024 版本开始支持 over PARTITION BY 的语法,之前的版本不支持

示例

在oracle和KingbaseES数据库创建表并插入数据

CREATE TABLE EMP (EMPNO NUMBER(4) NOT NULL,
ENAME VARCHAR2(10),
JOB VARCHAR2(9),
SAL NUMBER(7, 2),
DEPTNO NUMBER(2)); INSERT INTO EMP VALUES (1, 'SMITH', 'CLERK', 800, 20);
INSERT INTO EMP VALUES (2, 'ALLEN', 'SALESMAN', 1600, 30);
INSERT INTO EMP VALUES (3, 'WARD', 'SALESMAN', 1250, 30);
INSERT INTO EMP VALUES (4, 'JONES', 'MANAGER', 2975, 20);
INSERT INTO EMP VALUES (5, 'MARTIN','SALESMAN', 1250, 30);
INSERT INTO EMP VALUES (6, 'BLAKE', 'MANAGER', 2850, 30);
INSERT INTO EMP VALUES (7, 'CLARK', 'MANAGER', 2850, 10);
INSERT INTO EMP VALUES (8, 'SCOTT', 'ANALYST', 3000, 20);
INSERT INTO EMP VALUES (9, 'KING', 'PRESIDENT',3000, 10);
INSERT INTO EMP VALUES (10,'TURNER','SALESMAN', 1500, 30);
INSERT INTO EMP VALUES (11,'ADAMS', 'CLERK', 1500, 20); oracle
TEST@orclpdb> SELECT MEDIAN(sal) FROM emp; MEDIAN(SAL)
-----------
1600 TEST@orclpdb> SELECT MEDIAN(sal) over (partition by deptno) avg,deptno from emp; AVG DEPTNO
---------- ----------
2925 10
2925 10
2237.5 20
2237.5 20
2237.5 20
2237.5 20
1500 30
1500 30
1500 30
1500 30
1500 30 KingbaseES test=# select percentile_cont(0.5) within group (order by sal) from emp;
percentile_cont
-----------------
1600
(1 行记录) test=# select percentile_cont(0.5) within group (order by sal) over (partition by deptno) ,deptno from emp;
percentile_cont | deptno
-----------------+--------
2925 | 10
2925 | 10
2237.5 | 20
2237.5 | 20
2237.5 | 20
2237.5 | 20
1500 | 30
1500 | 30
1500 | 30
1500 | 30
1500 | 30
(11 行记录) test=# select percentile_disc(0.5) within group (order by sal) from emp;
percentile_disc
-----------------
1600.00
(1 行记录) test=# select percentile_disc(0.5) within group (order by sal) over (partition by deptno) ,deptno from emp;
percentile_disc | deptno
-----------------+--------
2850.00 | 10
2850.00 | 10
1500.00 | 20
1500.00 | 20
1500.00 | 20
1500.00 | 20
1500.00 | 30
1500.00 | 30
1500.00 | 30
1500.00 | 30
1500.00 | 30
(11 行记录) 删除处于中位数的数据再进行测试(id=2,sal=1600)
KingbaseES test=# delete from emp where empno =2 ;
DELETE 1
test=# select percentile_cont(0.5) within group (order by sal) from emp;
percentile_cont
-----------------
2175
(1 行记录) test=# select percentile_cont(0.5) within group (order by sal) over (partition by deptno) ,deptno from emp;
percentile_cont | deptno
-----------------+--------
2925 | 10
2925 | 10
2237.5 | 20
2237.5 | 20
2237.5 | 20
2237.5 | 20
1375 | 30
1375 | 30
1375 | 30
1375 | 30
(10 行记录) test=# select percentile_disc(0.5) within group (order by sal) from emp;
percentile_disc
-----------------
1500.00
(1 行记录) test=# select percentile_disc(0.5) within group (order by sal) over (partition by deptno) ,deptno from emp;
percentile_disc | deptno
-----------------+--------
2850.00 | 10
2850.00 | 10
1500.00 | 20
1500.00 | 20
1500.00 | 20
1500.00 | 20
1250.00 | 30
1250.00 | 30
1250.00 | 30
1250.00 | 30
(10 行记录) oracle TEST@orclpdb> SELECT MEDIAN(sal) FROM emp; MEDIAN(SAL)
-----------
2175 TEST@orclpdb> SELECT MEDIAN(sal) over (partition by deptno) avg,deptno from emp; AVG DEPTNO
---------- ----------
2925 10
2925 10
2237.5 20
2237.5 20
2237.5 20
2237.5 20
1375 30
1375 30
1375 30
1375 30 10 rows selected.

从测试结果看percentile_cont(0.5)函数与oracle的MEDIAN函数结果是一致的,可以进行完美替换。

percentile_disc(0.5) 和 percentile_cont(0.5) 在特定的情况下结果会一致(数据集为奇数的时候)

KingbaseES 使用百分比函数获取中位数的更多相关文章

  1. ReportingService 通过RowNumber函数获取行号和生成隔行变色样式

    以前一直没有搞明白SSRS里面的RowNumber函数到底该怎么用,所以一直没有很好的办法在SSRS中的表格上实现隔行变色的样式,实现隔行变色的关键就是获取表格中每一行的行号.在最近了解了下这个函数, ...

  2. MySql中使用日期函数获取昨天的数据

    .body-classic{ color:#444; font-family:Georgia, Palatino, 'Palatino Linotype', Times, 'Times New Rom ...

  3. 使用sqlserver日期函数获取当前日期

    使用sqlserver日期函数中的getdate()可以获取当现的日期,下面就将为您介绍这种使用sqlserver日期函数获取当前日期的方法,供您参考,希望对您学习sqlserver日期函数有所启迪. ...

  4. inux关于readlink函数获取运行路径的小程序

    inux关于readlink函数获取运行路径的小程序   相关函数: stat, lstat, symlink 表头文件: #include <unistd.h> 定义函数:int  re ...

  5. Delphi调用API函数获取Windows目录信息、获取System目录信息、获取Temp临时文件目录信息

    var Str1, Str2: Array[..Max_Path]of Char;//开辟缓冲区 Str3: Array[..]of Char; begin GetWindowsDirectory(@ ...

  6. 『转载』Matlab中fmincon函数获取乘子

    Matlab中fmincon函数获取乘子 一.输出结构 [x,fval,exitflag,output,lambda] = fmincon(......) 二.结构说明 lambda结构 说     ...

  7. 帝国cms使用自定义函数获取新闻文章数 实例分享

    原文地址:http://www.jbxue.com/cms/24337.html 介绍了帝国cms系统中通过用户自定义函数获取用户发表新闻数量的方法,主要是分享下帝国cms自定义函数功能. 在帝国cm ...

  8. MySQL内置函数获取几天前的日期

    如何采用mysql内置函数获取指定时间之前的日期呢? SELECT something FROM table_name WHERE DATE_SUB(CURDATE(),INTERVAL 30 DAY ...

  9. php -- PHP5中file_get_contents函数获取带BOM的utf-8文件内容

    最近,在用file_get_contents函数来取得文本的内容的时候,出现了一个情况(如下),苦思冥想了n久,不得其解,最后,果然还是得靠百度啊..... 百度到一个解释,下面是原文: PHP5中的 ...

  10. 第九篇:使用 lstat 函数获取文件信息

    前言 在之前的文章中,描述过如何用 fcntl 函数改变文件的状态标记.但,文件还有很多信息,如文件类型,权限设置,设备编号,访问时间等等.如果要获取这些信息,则使用函数 lstat 可以轻松达到这个 ...

随机推荐

  1. Ubuntu在无网络环境下,用离线源apt-get安装软件

    步骤概要如下: 1.假设目标安装的是服务器A,需先准备一台正常环境,且操作系统版本与A一致的服务器B: 2.用apt-get在服务器B上下载需要安装的包,并用dpkg-scanpackages依赖打包 ...

  2. mysql-5.7.16-winx64配置文件

    # For advice on how to change settings please see # http://dev.mysql.com/doc/refman/5.7/en/server-co ...

  3. 获取Linux mac地址(centos与ubuntu通用)

    ip -a addr| grep link/ether | awk '{print $2}'| head -n 1 获取Linux mac地址(centos与ubuntu通用)

  4. 关于 try... catch

    在逛论坛看见一个有意思的帖子,有点意思,记录下 关于"异常捕捉"(try catch)是否存在悖论? 一些我觉得有用的回复,放到下面了, 1. 当某些错误状况难以完全避免时,try ...

  5. 使用SecScanC2构建P2P去中心化网络实现反溯源

    个人博客: xzajyjs.cn 前言 这款工具是为了帮助安全研究人员在渗透测试过程中防止扫描被封禁.保护自己免溯源的一种新思路.其利用到了区块链中的p2p点对点去中心化技术构建以来构建代理池. 工具 ...

  6. 并发慎用——System.currentTimeMillis()

    好记忆不如烂笔头,能记下点东西,就记下点,有时间拿出来看看,也会发觉不一样的感受. System.currentTimeMillis()是极其常用的基础Java API,广泛地用来获取时间戳或测量代码 ...

  7. .NET高级调试之sos命令输出看不懂怎么办

    一:背景 1. 讲故事 很多.NET开发者在学习高级调试的时候,使用sos的命令输出会发现这里也看不懂那里也看不懂,比如截图中的这位朋友. .NET高级调试属于一个偏冷门的领域,国内可观测的资料比较少 ...

  8. Redis之数据持久化小结

    一.概述 Redis作为内存型的数据库,虽然很快,依然有着很大的隐患,一旦服务器宕机重启,内存中数据还会存在吗? 很容易想到的一个方案是从后台数据恢复这些数据,如果数据量很小,这倒是一个可行的方案.但 ...

  9. Java核心之细说泛型

    泛型是什么? 等你使用java逐渐深入以后会了解或逐步使用到Java泛型.Java 中的泛型是 JDK 5 中引入的功能之一."Java 泛型 "是一个技术术语,表示一组与定义和使 ...

  10. Failed to collect dependencies at com.oneconnect......-Intellij-IDEA-使用maven打包采坑记录

    一.问题由来 由于刚开始使用Intellij-IDEA,使用不是很熟练,因此使用过程中出现各种各样的问题.最近开发过程中,准备使用IDEA打包项目发布到测试服务器,报错信息如下: Failed to ...