龙空技术网

Presto或Mysql取中位数

囍囍临猿 95

前言:

今天姐妹们对“mysql取第二条”大致比较注重,小伙伴们都想要剖析一些“mysql取第二条”的相关内容。那么小编同时在网上搜集了一些关于“mysql取第二条””的相关文章,希望咱们能喜欢,咱们一起来了解一下吧!

什么是中位数

中位数是指将数据按大小顺序排列,位于中间位置的那个数据,其可将数值集合划分为相等的上下两部分。

money的中位数

举个例子,如上图红框中数据,总共11条数据,money字段中位数就是排序后第六条数据。

思路

1、总条数为奇数,中位数为位于(总条数+1)/ 2那条数据。

2、总条数为偶数,则需要根据自己实际业务来取,可以是位于(总条数/2)的那条数据,也可以是位于(总条数/2)+1的那条数据,也可以是中间位置的两条数据取平均值作为中位数。

实现

按图中所示,总共四条数据,以取(总条数/2)+1为例,sale_sales_volume中位数等于287,sale_return_goods_number中位数等于57。

1、presto中提供了approx_percentile(col, p, B)函数

WITH origin_table AS (    SELECT SUM(byorder_sales_volume) AS "sale_sales_volume",           SUM(report_refund_num) AS "sale_return_goods_number"   FROM dws.dws_report_001 AS report   WHERE report.user_id=102   ),median_table AS (    SELECT approx_percentile(sale_sales_volume, 0.5) AS sale_sales_volume,   							approx_percentile(sale_return_goods_number, 0.5) AS sale_return_goods_number 		FROM origin_table    )SELECT median_table.* FROM median_table;

使用approx_percentile结果

2、按取数逻辑(总条数/2)+1

WITH origin_table AS (    SELECT SUM(byorder_sales_volume) AS "sale_sales_volume",           SUM(report_refund_num) AS "sale_return_goods_number"   FROM dws.dws_report_001 AS report   WHERE report.user_id=102   ),volume_table AS (    SELECT sale_sales_volume, row_number() over(ORDER BY sale_sales_volume) num, count(*) over() cnt FROM origin_table    ),median_volume_table AS (    SELECT sale_sales_volume FROM volume_table WHERE if(cnt % 2 = 0, num = ((cnt / 2) + 1), num = (cnt + 1) / 2)    ),return_table AS (    SELECT sale_return_goods_number, row_number() over(ORDER BY sale_return_goods_number) num, count(*) over() cnt FROM origin_table    ),median_return_table AS (    SELECT sale_return_goods_number FROM return_table WHERE if(cnt % 2 = 0, num = ((cnt / 2) + 1), num = (cnt + 1) / 2)    )SELECT median_volume_table.*, median_return_table.*FROM median_volume_table, median_return_table;

按逻辑取的结构

可以看出,两种方法结果是一致的。

示例中的表名、where条件是经过修改,只作为例子。

对比

1、presto中approx_percentile,原生支持,性能好,但有精度问题,col的条数大于B,会有误差.。

2、mysql8中可以采用第二种方法,可以根据实际业务需求来取,比较灵活,但缺点就是慢。

标签: #mysql取第二条 #mysql位数