客户从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. 2024-02-24:用go语言,给你一个 n 个点的带权无向连通图,节点编号为 0 到 n-1, 同时还有一个数组 edges ,其中 edges[i] = [fromi, toi, weighti

    2024-02-24:用go语言,给你一个 n 个点的带权无向连通图,节点编号为 0 到 n-1, 同时还有一个数组 edges ,其中 edges[i] = [fromi, toi, weighti ...

  2. render_to_string快捷函数,渲染模板字符串

    # views.py from django.template.loader import render_to_string from django.http import HttpResponse ...

  3. Gin框架使用jwt-go配合中间件认证

    参考文档 // 文档 https://github.com/golang-jwt/jwt https://pkg.go.dev/github.com/golang-jwt/jwt@v3.2.2+inc ...

  4. npm模块全局安装后无法使用解决方案

    好家伙 npm模块全局安装后无法使用   估计是少配了环境变量 1.使用命令: npm config get prefix 找到全局包的安装位置   2.随后我们右键"我的电脑"打 ...

  5. 【Azure Developer】CURL 发送Oauth2 Token请求获取到 404 Not Found 问题

    问题描述 当使用 Postman 向AAD 发送如下请求时候,得到了404 Not Found的错误. "curl --location --request POST 'https://lo ...

  6. 2024年,提升Windows开发和使用体验实践 - 小工具篇

    前言 本来是一篇文章的,不知不觉写成了系列. 其实开工那几天就已经写好了长文,这几天一忙就没连着发了. 本文介绍一些 Windows 上用的小工具. 美化/折腾/小工具 虽然这是在用 Windows ...

  7. 关于Cortex-M3报错解决方法总结:Flash Download failed错误

    事情原因:在一次使用ST-LINK v2下载程序时,突然出现 Error:Flash Download Failed-"Cortex-M3"这个错误,显示没有错误,没有警告.芯片型 ...

  8. C++ STL函数对象 仿函数

    1 //STL函数对象 仿函数 2 #include<iostream> 3 #include<string> 4 5 using namespace std; 6 7 8 / ...

  9. 虚拟机和开发板之间通过NFS互联

    简介 NFS是Network File System的首字母缩写.它是一种分布式协议,使客户端可以访问远程服务器上的共享文件.它允许网络中的计算机之间通过TCP/IP网络共享资源. 配置过程 安装NF ...

  10. manjaro蓝牙链接不上或者连接上了没有声音

    查看这些软件宝有没有安装上:sudo pacman -S bluez bluez-utils pulseaudio-bluetooth pavucontrol pulseaudio-alsa puls ...