讲师中心 微信公众号
AI工具推荐 视频效率加速

SQL如何实现分组内的中值绝对偏差_编写自定义聚合逻辑

阿浩君_7575

阿浩君_7575

发布时间:2026-04-21 11:52:20

|

418人浏览过

|

来源于php中文网

原创

PostgreSQL中计算分组MAD需分两步:先用PERCENTILE_CONT(0.5)求各组中位数,再计算绝对偏差并对其求中位数;MySQL需用窗口函数模拟中位数并注意偶数长度取平均;SQLite受限需JSON聚合+外部计算或退化为AAD。

sql如何实现分组内的中值绝对偏差_编写自定义聚合逻辑

PostgreSQL里用percentile_cont快速算分组内MAD

中值绝对偏差(MAD)不是内置聚合函数,但PostgreSQL的percentile_cont可以绕过手写排序逻辑。关键在于:先按组求中位数,再对每行算绝对偏差,最后对偏差序列再求中位数。

常见错误是试图在一个聚合里嵌套两次中位数计算——这会报错subquery in aggregate context。正确做法是用WITH或窗口函数分两步走:

  • 第一步:用PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY x)算出每组的中位数med
  • 第二步:用ABS(x - med)生成偏差列,再对其调用PERCENTILE_CONT(0.5)

示例(按category分组):

WITH medians AS (
  SELECT category,
         PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY value) AS med
  FROM data_table
  GROUP BY category
)
SELECT m.category,
       PERCENTILE_CONT(0.5) WITHIN GROUP (
         ORDER BY ABS(d.value - m.med)
       ) AS mad
FROM data_table d
JOIN medians m ON d.category = m.category
GROUP BY m.category;

MySQL 8.0+用窗口函数模拟median实现MAD

MySQL没有percentile_cont,但可用ROW_NUMBER()和COUNT(*)手动定位中位数位置。难点在于:中位数本身需要窗口计算,而MAD又依赖这个中位数,所以必须用两层子查询或CTE。

容易踩的坑是忽略偶数长度时中位数要取中间两数平均值——直接用FLOOR((cnt+1)/2)只拿到下中位数,会导致MAD偏小。

  • 先用COUNT(*) OVER (PARTITION BY category)得每组总数cnt
  • 再用ROW_NUMBER() OVER (PARTITION BY category ORDER BY value)给每行编号
  • 筛选出第FLOOR((cnt+1)/2)和CEIL((cnt+1)/2)行,取平均得中位数
  • 最后对ABS(value - med)重复上述流程

性能上,两次全量排序开销大,数据量超10万行建议加(category, value)联合索引。

SQLite里用json_group_array + 自定义函数补足缺失能力

SQLite连窗口函数都受限(3.25+才支持),原生无法做分组中位数。可行路径是:把每组value聚合成JSON数组,再用Python或JavaScript扩展写一个mad()函数解析并计算。

但要注意:默认编译的SQLite不启用json扩展,执行前先确认SELECT json_array(1,2);是否返回[1,2];否则需重新编译或换用spatialite等增强版。

  • 聚合阶段:SELECT category, json_group_array(value) AS vals FROM t GROUP BY category
  • 在应用层解析vals为列表,用numpy.median(np.abs(arr - np.median(arr)))算MAD
  • 若坚持纯SQL,只能退化为近似法:用AVG(ABS(value - (SELECT AVG(value) FROM ...)))——但这算的是平均绝对偏差(AAD),不是MAD

为什么不能直接用AVG(ABS(value - MEDIAN(value)))?

因为几乎所有SQL引擎都不允许在聚合函数里嵌套另一个非标量聚合(如MEDIAN)。即使某些方言看似支持,实际执行时也会报错misuse of aggregate: median或静默返回NULL。

根本矛盾在于:中位数是顺序敏感的统计量,必须先完成分组、排序、定位三步,而标准SQL的聚合执行模型要求所有聚合函数独立作用于同一行集——它无法表达“先按组求中位数,再用该中位数参与下一轮聚合”这种依赖关系。

真正复杂的地方不在公式本身,而在如何把“中位数作为中间变量”这件事,在不同引擎的执行计划约束下安全落地。别被函数名迷惑,重点始终是数据流的分阶段可控性。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

4003

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

851

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

1049

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

5861

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2783

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

5840

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

7761

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

1050

2024.04.29

LLVM自定义Pass怎么写
LLVM自定义Pass怎么写

本专题聚焦LLVM自定义Pass开发,整理Pass类结构、run()方法、PreservedAnalyses、CMake构建、插件注册、-load-pass-plugin加载和测试用例编写流程。

80

2026.09.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn