【问题标题】:Grouping rows with condition使用条件对行进行分组
【发布时间】:2016-12-01 03:54:07
【问题描述】:

我有以下型号:

class Datacomponent(models.Model):
        id = models.IntegerField(db_column='ID', primary_key=True)  # Field name made lowercase.
        composition = models.ForeignKey(Composition, models.DO_NOTHING, db_column='Composition_ID', null=True, blank=True)  # Field name made lowercase.
        components = models.ForeignKey(Components, models.DO_NOTHING, db_column='Components_ID')  # Field name made lowercase.
        componentvalue = models.FloatField(db_column='ComponentValue')  # Field name made lowercase.



class Components(models.Model):
    id = models.IntegerField(db_column='ID', primary_key=True)  # Field name made lowercase.
    name = models.CharField(db_column='Name', max_length=45, blank=True, null=True)  # Field name made lowercase.

Datacomponent 中有多行相同的组合(这是Composition 表的外键)。

如果它的每个组件值都在某些值的范围内,我的最终目标是获得一组 Composition。在下面显示的方法中,我根本没有得到任何 composition_ids。

CompositionID   ComponentID  ComponentValue
   1               1            0.5
   1               2            0.3
   2               1            0.6
   2               2            0.4
   3               1            0.0
   3               2            0.1

所以对上表的查询将是:'获取所有 componentid=1 和 componentvalue__range=(minn[a], maxx[b]) 的组合 ID。如果我们想要componentID 1 的comp 值gte 0.5 和componentID 2 的gte 0.3,我们的结果应该只是2,因为2 的组件1 是0.6,而component2 的值是0.4。

这是我的方法不起作用:

    queries = [Q(componentvalue__range = (minn[v], maxx[v]),
                 components__name    = "'"+v+"'",
                ) for v in minn]

    query = queries.pop()
    for item in queries:
        query |= item

    composition_ids = Datacomponent.objects.filter(query).values_list('composition_id', flat=True)

    print (composition_ids.count())

【问题讨论】:

    标签: python django django-models


    【解决方案1】:

    如果我理解正确,那么这样的事情可能会有所帮助

    在您发表评论后进行编辑。 (我希望这次我能更好地理解你)。你实际上是在Composition 对象之后,comp1 和 comp2 在指定范围内(?)然后你实际上可以从Composition 模型中选择它们。

    首先在Datacomponent 模型中的composition 字段中添加一个related_name,类似于“datacomp”,用于反向查询。

    from django.db.models import Q
    
    class Datacomponent(models.Model):
        composition = models.ForeignKey(Composition, related_name='datacomp', ..) 
        ...
    
    comp_1_query = Q(datacomp__components_id=YOUR_COMP1_ID, datacomp__componentvalue_range=(YOUR_RANGE1_MIN, YOUR_RANGE1_MAX)
    comp_2_query = Q(datacomp__components_id=YOUR_COMP2_ID, datacomp__componentvalue_range=(YOUR_RANGE2_MIN, YOUR_RANGE2_MAX)
    
    
    Composition.objects\
               .select_related('datacomp')\ # you can for optimization  
               .filter(comp_1_query, comp_2_query)\ # Simply 'and' since you want both to match
               .values_list('id', 'datacomp__components_id', 'datacomp__componentvalue', flat=True)
    

    这应该为您提供指定范围内的组件 1 和组件 2 的组合。

    【讨论】:

    • 我认为您的解决方案正是我在 OP 中展示的。这里的问题是,如果用户为组件 1 输入 (0.5, 0.6),为组件 2 输入 (0.2, 0.3),那么由于我们结合了or,因此组合 1 和组合 2 都会显示在结果中。所需的结果只是 composition1 在结果中,因为它匹配两个条件。
    • 我现在更好地理解了你的问题。您实际上是在追求同时具有匹配标准的 comp1 和 comp2 的作品吗?编辑了答案。
    猜你喜欢
    • 1970-01-01
    • 2021-07-28
    • 1970-01-01
    • 1970-01-01
    • 2020-10-22
    • 2016-09-14
    • 2014-06-30
    • 2021-08-29
    • 1970-01-01
    相关资源
    最近更新 更多