You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django注解实现中位数计算 基于MySQL5.8的ORM分组查询方案

Django ORM + MySQL 5.8 实现分组统计价格中位数方案

MySQL 5.8(即后续正式命名的MySQL 8.0版本)已经内置了百分位计算函数,你可以通过Django自定义聚合函数的方式直接在ORM层实现中位数统计,无需额外处理。

方案1:ORM层直接计算(推荐,大数据量适用)

第一步:定义自定义中位数聚合类

from django.db.models import Aggregate, FloatField

class Median(Aggregate):
    # PERCENTILE_CONT 为连续插值中位数,需要取实际存在的数值可替换为 PERCENTILE_DISC
    function = 'PERCENTILE_CONT'
    name = 'median'
    template = '%(function)s(0.5) WITHIN GROUP (ORDER BY %(expressions)s)'
    output_field = FloatField()

第二步:替换原查询中的median字段

price_query = Product.objects \
    .filter(price_query) \
    .annotate(dt=Trunc('StartDate', frequency)) \
    .values('dt') \
    .annotate(
        avg_price=Avg('Price'), 
        std_price=StdDev('Price'),
        count=Count('Price'), 
        max_price=Max('Price'),
        min_price=Min('Price'), 
        median=Median('Price') # 仅需替换此处即可
    ) \
    .order_by('dt')

该方案直接在数据库层计算,性能和原生SQL一致,返回结果完全匹配你给出的JSON格式要求。

方案2:Python层计算(小数据量适用)

如果你的MySQL版本实际低于8.0不支持窗口函数,且数据量不大,可以先拉取分组后的所有价格,在Python层计算指标:

from collections import defaultdict
from statistics import mean, stdev, median

# 拉取所有符合条件的日期和对应价格
raw_items = Product.objects.filter(price_query)\
    .annotate(dt=Trunc('StartDate', frequency))\
    .values('dt', 'Price')\
    .order_by('dt')

# 按日期分组计算
grouped = defaultdict(list)
for item in raw_items:
    grouped[item['dt']].append(item['Price'])

result = []
for dt, prices in grouped.items():
    prices.sort()
    result.append({
        "date": dt,
        "avg_price": mean(prices),
        "std_price": stdev(prices) if len(prices)>=2 else 0,
        "min_price": min(prices),
        "max_price": max(prices),
        "count": len(prices),
        "median": median(prices)
    })

注意事项

  • 若执行方案1时提示函数不存在,可确认你的MySQL版本是否为8.0系列(MySQL 8.0开发阶段曾短暂使用5.8作为版本号命名),低于该版本无法直接使用内置百分位函数。
  • PERCENTILE_CONT返回的是插值后的连续值,PERCENTILE_DISC返回的是数据集中实际存在的数值,可根据业务需求选择替换。

内容的提问来源于stack exchange,提问作者party911

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 03:45:04