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

如何通过Django模型查询本月销售额较上月增长超20%的公司

实现本月销售额较上月增长超20%的公司查询

要实现这个需求,我们可以通过Django的子查询、注解(annotate)和字段表达式(F())关联每个公司的本月与上月销售额,再筛选出符合增长条件的公司。以下是具体实现方案:

前提说明

假设每个公司每月仅生成一份MonthlyReport,如果存在同一公司一月多份报告的情况,需要将代码中的单条销售额替换为月度销售额总和(使用Sum聚合函数)。

实现步骤

1. 导入必要模块

from django.db.models import F, Subquery, OuterRef, Sum
from django.utils import timezone
from datetime import timedelta
from .models import Company, MonthlyReport

2. 计算本月与上月的日期范围

先确定当前月份和上月的起止日期,确保日期过滤的准确性:

today = timezone.now().date()
# 本月起始日期(当月1号)
this_month_start = today.replace(day=1)
# 下月起始日期(用于过滤本月数据,date__lt=next_month_start)
next_month_start = (this_month_start + timedelta(days=32)).replace(day=1)
# 上月结束日期(本月1号前一天)
last_month_end = this_month_start - timedelta(days=1)
# 上月起始日期(上月1号)
last_month_start = last_month_end.replace(day=1)

3. 定义子查询获取月度销售额

分别定义子查询,获取每个公司的本月销售额和上月销售额:

# 子查询:获取每个公司的本月销售额(若多份报告则求和)
this_month_sales = MonthlyReport.objects.filter(
    company=OuterRef('pk'),
    date__gte=this_month_start,
    date__lt=next_month_start
).aggregate(total=Sum('sale')).values('total')[:1]

# 子查询:获取每个公司的上月销售额(若多份报告则求和)
last_month_sales = MonthlyReport.objects.filter(
    company=OuterRef('pk'),
    date__gte=last_month_start,
    date__lte=last_month_end
).aggregate(total=Sum('sale')).values('total')[:1]

4. 查询符合条件的公司

通过注解关联两个子查询的结果,筛选出增长超过20%的公司(同时排除上月销售额为0的情况,避免计算错误):

target_companies = Company.objects.annotate(
    current_sale=Subquery(this_month_sales),
    prev_sale=Subquery(last_month_sales)
).filter(
    prev_sale__gt=0,  # 排除上月无销售额或销售额为0的公司
    current_sale__gt=F('prev_sale') * 1.2  # 本月销售额 > 上月的120%
)

可选:通过MonthlyReport自连接实现

也可以直接从MonthlyReport入手,关联本月和上月的记录,再反向获取公司:

# 先筛选出本月的报告,注解上月销售额
qualified_reports = MonthlyReport.objects.filter(
    date__gte=this_month_start,
    date__lt=next_month_start
).annotate(
    prev_month_sale=Subquery(
        MonthlyReport.objects.filter(
            company=F('company'),
            date__gte=last_month_start,
            date__lte=last_month_end
        ).aggregate(total=Sum('sale')).values('total')[:1]
    )
).filter(
    prev_month_sale__gt=0,
    sale__gt=F('prev_month_sale') * 1.2
)

# 从符合条件的报告中提取对应的公司
target_companies = Company.objects.filter(id__in=qualified_reports.values('company__id')).distinct()

注意事项

  • 若业务允许公司某月无报告,可根据需求调整过滤条件(比如保留current_sale或prev_sale为None的情况,但需处理空值逻辑)。
  • 日期处理使用django.utils.timezone确保时区一致性,避免因服务器时区导致的日期偏差。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 10:33:20