如何从查询集中选择数据并按特定数据的计数分组

2024-09-30 00:22:25 发布

您现在位置:Python中文网/ 问答频道 /正文

当我查询我的数据库时,我用三个不同的计数得到三次相同的条目。在结果列表中,我只想得到一个显示这些计数总和的条目

我想显示的是特定时期的总数

在我的查询中,我输入日期(从-到),度量类型,数据类型和出版年份

例如,我在网站上,当我进入

from 201903 until 201905 

我检索了在这段时间内被访问的三个标题以及它们被访问的次数

Title, Publisher,    DOI,   data_type,YOP,[some other stuff] Counts

Title A  publisherA   1234    Article, 2006, [some_other_stuff], 3
Title A  publisherA   1234    Article, 2006, [some_other_stuff], 5
Title A  publisherA   1234    Article, 2006, [some_other_stuff], 3

我需要的是

Title, publisher, DOI,   data_type, YOP,  [some_other_stuff],  Total period

Title A, publisherA 1234   Article, 2006,   [some_other_stuff],    11


在views.py中,我有以下代码:

    q_report = Q()


        var0 = self.request.GET.get("period1", "")
        var1 = self.request.GET.get("period2", "")
        var2 = self.request.GET.get("metric_type", "")
        var3 = self.request.GET.get("data_type", "")
        var4 = self.request.GET.get("YOP", "")



        if var0:
            q_report = q_report & (Q(month__gte=var0) & Q(month__lte=var1) )
            #q_report_count = q_report_count & (Count(month__gte=var0) & Count(month__lte=var1) )
        if var2:
            q_report = q_report & (Q(metric_type=var2))
            #q_report_count = q_report_count & (Q(metric_type=var2))
        if var3:
             q_report = q_report & (Q(data_type=var3))
        if var4:
             q_report = q_report & (Q(YOP=var4))

如果我使用

qs = self.model.objects.filter(q_report).select_related()

我要拿回三个条目

结果是

<QuerySet [<Model: Title A>, <Model: Title A>, <Model: Title A>]>

我可以很容易地用

total = self.model.objects.aggregate(total=Sum('counts', filter=q_report))

结果是

{total : 11.0}

但理想情况下,我需要得到其他值以及

现在,我看不出我怎样才能把这两者结合起来,比如


<QuerySet [<Model: {'title':Title A, 'total':11}>, Model: {'title':Title B, 'total':7}>]

我甚至不知道这是可能的还是需要的。但我要把查询集和总数都还给你

有人能帮忙吗?谢谢


Tags: selfreportdatagetmodeltitlerequesttype
2条回答

这本质上是一个建模问题。而不是像这样定义一个模型:

# modeling with data duplication

class SomeModel(models.Model):
    title = models.CharField(max_length=256)
    publisher = models.CharField(max_length=256)
    doi = models.CharField(max_length=256)
    publication_type = models.CharField(max_length=128)
    year = models.IntegerField()
    date = models.DateField()
    counts = models.IntegerField()

您应该创建一个类似Publication的模型,并将SomeModel链接到该Publication,如:

# modeling without data duplication

class Publication(models.Model):
    title = models.CharField(max_length=256)
    publisher = models.CharField(max_length=256)
    doi = models.CharField(max_length=256)
    publication_type = models.CharField(max_length=128)
    year = models.IntegerField()

class PublicationSale(models.Model):
    publication = models.ForeignKey(Publication, on_delete=models.CASCADE)
    date = models.DateField()
    counts = models.IntegerField()

这将减少数据库的大小,降低数据库不一致的可能性(例如,如果更改发布年份,某些记录未正确更新),并可能使数据库在某些查询中运行得更快

在这种情况下,您可以像这样查询:

from django.db.models import Sum

Publication.objects.annotate(
    total=Sum('publication_sale__counts')
)

然后检索带有Publication对象的QuerySet,该对象带有一个额外属性.totals,即与相关的PublicationSale对象的counts之和

如果不进行此重塑,可以使用:

from django.db.models import Sum

qs = self.model.objects.filter(q_report).values(
    'title', 'publisher', 'doi', 'publication_type', 'year'
).annotate(
    total=Sum('counts')
).order_by(
    'title', 'publisher', 'doi', 'publication_type', 'year'
)

然后产生QuerySet个字典:

<QuerySet [
    {'title': 'Title A', 'publisher': 'pubA', ..., 'total': 11},
    {'title': 'Title B', 'publisher': 'pubA', ..., 'total': 7},
    {'title': 'Title A', 'publisher': 'pubB', ..., 'total': 3},
]>

但是正如您所看到的,查询不会产生模型,而且有点“不稳定”,即每次添加“功能相关实体”的额外数据时,都需要更新查询

将查询替换为

self.model.objects.filter(q_report).annotate(total=Sum('counts')).values('title','total')

其中total是要求和的字段

相关问题 更多 >

    热门问题