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

在Django中筛选收支金额匹配的非零记录(附MySQL示例)

在Django中筛选收支金额匹配的记录(数万条数据场景)

需求分析

需要筛选出满足以下条件的记录:

  • 排除收入或支出为0.00且无对应匹配金额的记录
  • 若记录收入>0.00,则表中存在至少一条支出等于该收入金额的记录
  • 若记录支出>0.00,则表中存在至少一条收入等于该支出金额的记录

前提假设

假设你的Django模型定义如下:

class Record(models.Model):
    id = models.AutoField(primary_key=True)
    income = models.DecimalField(max_digits=10, decimal_places=2)
    expense = models.DecimalField(max_digits=10, decimal_places=2)

实现方案

方案一:Django ORM 高效实现(推荐)

使用Exists子查询和Q对象组合条件,半连接查询性能更优,适配数万条数据场景:

from django.db.models import Q, Exists, OuterRef

# 子查询:检查当前收入金额是否存在对应的有效支出记录
has_matching_expense = Record.objects.filter(
    expense=OuterRef('income'),
    expense__gt=0
)

# 子查询:检查当前支出金额是否存在对应的有效收入记录
has_matching_income = Record.objects.filter(
    income=OuterRef('expense'),
    income__gt=0
)

# 筛选符合条件的记录
matched_records = Record.objects.filter(
    Q(income__gt=0, exists=Exists(has_matching_expense)) |
    Q(expense__gt=0, exists=Exists(has_matching_income))
)

方案二:原生SQL实现

如果需要更灵活的查询控制,可直接使用原生SQL:

from django.db import connection

with connection.cursor() as cursor:
    cursor.execute("""
        SELECT r.*
        FROM your_table r
        WHERE 
            (r.income > 0 AND EXISTS (SELECT 1 FROM your_table WHERE expense = r.income AND expense > 0))
            OR
            (r.expense > 0 AND EXISTS (SELECT 1 FROM your_table WHERE income = r.expense AND income > 0));
    """)
    # 可选:将查询结果转换为Record模型实例
    matched_records = Record.objects.raw(cursor.query)

性能优化建议

针对数万条数据,建议给income和expense字段添加数据库索引,大幅提升查询速度:

# 修改模型字段,添加索引配置
income = models.DecimalField(max_digits=10, decimal_places=2, db_index=True)
expense = models.DecimalField(max_digits=10, decimal_places=2, db_index=True)

添加索引后,执行python manage.py makemigrations和python manage.py migrate完成索引创建。

结果验证

针对你提供的示例数据,执行上述代码后,将得到id为1、3、4、6、7的记录,与预期结果完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 08:10:24