如何用Django结合SQL的Join与Group By统计访客最多的国家?
获取访客数量最多的国家及其访客数
没问题,这个需求完全可以用Django ORM来实现,不用手写复杂的SQL,我给你两种常用的方案:
方案一:获取单个访客最多的国家(默认取第一个)
如果只需要拿到访客数量最多的那一个国家(即使有多个国家并列第一,也只取其中一个),可以用annotate+order_by的组合:
from django.db.models import Count # 给每个国家对象添加一个统计访客数的字段,然后按访客数倒序排列,取第一个结果 top_country = Country.objects.annotate(visitor_count=Count('visitor')).order_by('-visitor_count').first() # 输出结果 if top_country: print(f"访客最多的国家:{top_country.title},访客数:{top_country.visitor_count}")
代码解释:
annotate(visitor_count=Count('visitor')):给每个Country实例新增一个visitor_count属性,值是该国家关联的Visitor记录总数(这里的visitor是反向关联的名称,因为Visitor的外键是Country,Django默认的反向关联是小写模型名)。order_by('-visitor_count'):按访客数从多到少排序,负号表示倒序。first():取排序后的第一条数据,也就是访客数最多的国家。
方案二:获取所有访客数并列第一的国家
如果存在多个国家访客数相同且都是最大值的情况,想要把这些国家都找出来,可以分两步走:
from django.db.models import Count, Max # 第一步:先计算出最大的访客数 max_visitor_count = Visitor.objects.values('country').annotate(count=Count('id')).aggregate(max_count=Max('count'))['max_count'] # 第二步:筛选出所有访客数等于最大值的国家 top_countries = Country.objects.annotate(visitor_count=Count('visitor')).filter(visitor_count=max_visitor_count) # 遍历输出所有符合条件的国家 for country in top_countries: print(f"访客最多的国家:{country.title},访客数:{country.visitor_count}")
代码解释:
- 第一步先通过
values('country')按国家分组,统计每个国家的访客数,再用aggregate算出这些统计值里的最大值。 - 第二步用
annotate统计每个国家的访客数,再用filter筛选出访客数等于最大值的所有国家。
这样不管是单个还是多个并列第一的情况,都能完美解决啦~
内容的提问来源于stack exchange,提问作者Adam Smith
相关产品推荐
相关产品推荐

