百分位函数,指一组数据中特定百分比位置的值,最典型的就是中位数(50%)。其中percentile_cont为连续百分位,如果指定位置没有值,则会根据前后位置的值线性计算值,也就是返回值不一定是原来存在的值。percentile_disc则为不连续百分位,如果指定位置没有值,则会根据百分位计算一个最近的位置,并返回该值。本文介绍GBase 8a里这些函数的语法和使用样例。
目录导航
环境
版本
9.5.3.28.18
数据
gbase> select version();
+-------------------------------+
| version() |
+-------------------------------+
| 9.5.3.28.18.r1_patch.650ab97f |
+-------------------------------+
1 row in set (Elapsed: 00:00:00.00)
gbase> select name,id from t1 order by name,id;
+-------+------+
| name | id |
+-------+------+
| Name0 | 3 |
| Name0 | 6 |
| Name0 | 9 |
| Name1 | 1 |
| Name1 | 4 |
| Name1 | 7 |
| Name1 | 10 |
| Name2 | 2 |
| Name2 | 5 |
| Name2 | 8 |
+-------+------+
10 rows in set (Elapsed: 00:00:00.03)
percentile_cont
语法
PERCENTILE_CONT ( numeric_literal )
WITHIN GROUP ( ORDER BY order_by_expression [ ASC | DESC ] )
OVER ( [ <partition_by_clause> ] )
参数
numeric_literal
要计算的百分位数。 该值必须介于和 1.0
. 之间0.0
。
WITHIN GROUP(Order by)
指定要排序的数值列表,并计算百分位数。 仅允许一个 order_by_expression 。 默认的排序顺序为升序。
OVER ( <partition_by_clause> )
将子句生成的 FROM
结果集划分为应用百分位函数的分区。
执行样例
gbase> select name,id,percentile_cont(0.5)within group(order by id ) over(partition by name)contId from t1 order by name,id;
+-------+------+--------+
| name | id | contId |
+-------+------+--------+
| Name0 | 3 | 6 |
| Name0 | 6 | 6 |
| Name0 | 9 | 6 |
| Name1 | 1 | 5.5 |
| Name1 | 4 | 5.5 |
| Name1 | 7 | 5.5 |
| Name1 | 10 | 5.5 |
| Name2 | 2 | 5 |
| Name2 | 5 | 5 |
| Name2 | 8 | 5 |
+-------+------+--------+
10 rows in set (Elapsed: 00:00:00.08)
备注
当位置命中时,比如Name0,一共3个值(对应0,0.5,1),0.5正好对应第二个,返回6
当位置未命中时,比如Name1,一共4个值(0,1/3,2/3,1),0.5在1/3和2/3之间,做线性内插计算(V=值,P=位置)
V1+(V2-V1)/((P-P1)/(P2-P1))
4+(7-4)/((0.5-1/3)/(2/3-1/3)) = 5.5
- 2/3相比1/3的百分位差距为2/3-1/3=1/3
- 0.5相比1/3的百分位差距为0.5-1/3=1/6
- 0,5的位置占差距位置的百分比 1/6 / 1/3 = 1/2, 也就是1/3和2/3的中间
- 1/3和2/3对应的值差距为 7-4=3
- 0.5位置对应的插值为 3*1/2=1.5
- 加上基数1/3的值4, 4+1.5=5.5
percentile_disc
语法
PERCENTILE_DISC ( numeric_literal ) WITHIN GROUP ( ORDER BY order_by_expression [ ASC | DESC ] )
OVER ( [ <partition_by_clause> ] )
参数
numeric_literal
要计算的百分位数。 该值必须介于 0.0 和 1.0 之间。
WITHIN GROUP(Order by)
指定要排序的数值列表,并计算百分位数。 仅允许一个 order_by_expression 。 默认的排序顺序为升序。
OVER ( <partition_by_clause> )
将子句生成的 FROM
结果集划分为应用百分位函数的分区。
执行样例
gbase> select name,id,percentile_disc(0.5)within group(order by id ) over(partition by name)discId from t1 order by name,id;
+-------+------+--------+
| name | id | discId |
+-------+------+--------+
| Name0 | 3 | 6 |
| Name0 | 6 | 6 |
| Name0 | 9 | 6 |
| Name1 | 1 | 4 |
| Name1 | 4 | 4 |
| Name1 | 7 | 4 |
| Name1 | 10 | 4 |
| Name2 | 2 | 5 |
| Name2 | 5 | 5 |
| Name2 | 8 | 5 |
+-------+------+--------+
10 rows in set (Elapsed: 00:00:00.08)
备注
当位置命中时,比如Name0,一共3个值(对应0,0.5,1),0.5正好对应第二个,返回6
当位置未命中时,比如Name1,一共4个值(0,1/3,2/3,1),0.5与前后位置的距离1/3和2/3都是1/6相同,选择前面的。返回4
1/2-1/3=1/6
2/3-1/2=1/6
位置稍微靠后一点,比如0.500000001,则会因为离2/3更仅,返回其位置值7
gbase> select name,id,percentile_disc(0.500000001)within group(order by id ) over(partition by name)discId from t1 order by name,id;
+-------+------+--------+
| name | id | discId |
+-------+------+--------+
| Name0 | 3 | 6 |
| Name0 | 6 | 6 |
| Name0 | 9 | 6 |
| Name1 | 1 | 7 |
| Name1 | 4 | 7 |
| Name1 | 7 | 7 |
| Name1 | 10 | 7 |
| Name2 | 2 | 5 |
| Name2 | 5 | 5 |
| Name2 | 8 | 5 |
+-------+------+--------+
10 rows in set (Elapsed: 00:00:00.09)