在Django 2.0中使用条件表达式跨越多个关系

时间:2018-01-17 13:57:46

标签: sql django django-models django-queryset

考虑Django 2.0中的以下模型(伪代码):

class m_Discussion(models.Model):
    ...

class m_Comment(models.Model):
    fk_discussion = models.ForeignKey('m_Discussion', related_name='comments')

class m_Tag(models.Model):
    fk_comment = models.ForeignKey('m_Comment', related_name='tags')

我想得到所有至少有50%(任意)评论标记的讨论(即至少有一个标签)

我目前的解决方案如下:

m_Discussion.objects.annotate(
    ratio_tagged_comments=Cast(
        Sum(
            Case(
                When(
                    comments__tags__isnull=False,
                    then=1.0
                ),
                default=0.0,
                output_field=FloatField()
            )
        ) / F('count_comments'),  
        output_field=FloatField()
    )
).filter(
    ratio_tagged_comments__gte=0.5,
)

我担心comments__tags__isnull=False行。

这是如何运作的?

我在跨越多个关系时没有发现使用条件表达式。

SQL看起来大概如下:

SELECT 
    "corpus_m_discussion"."id_discussion", 
    "corpus_m_discussion"."title" 
FROM 
    "corpus_m_discussion" 
    LEFT OUTER JOIN "corpus_m_comment" ON (
        "corpus_m_discussion"."id" = "corpus_m_comment"."fk_discussion_id"
    ) 
    LEFT OUTER JOIN "corpus_m_tag" ON (
        "corpus_m_comment"."id" = "corpus_m_tag"."fk_comment_id"
    ) 
GROUP BY 
    "corpus_m_discussion"."id" 
HAVING 
    (
        COUNT("corpus_m_comment"."id") >= 5 
        AND (
            SUM(
                CASE WHEN ("corpus_m_tag"."id" IS NOT NULL) THEN 1.0 ELSE 0.0 END
            ) / (
                COUNT("corpus_m_comment"."id") -1
            )
        ):: double precision >= 0.7
    )

&#39; corpus_m_tag&#39;中的哪一行?表格在这里进行比较:CASE WHEN ("corpus_m_tag"."id" IS NOT NULL) THEN 1.0 ELSE 0.0 END。 对我而言,这似乎很奇怪,但我没有经历过在SQL中拥有&#39;,&#39; count&#39; count&#39; case&#39;,...子句。< / p>

赞赏任何输入

更新 我的主要问题是理解跨越多个关系的注释。我会理解一个只有一个关系的简单注释的查询,因为这些例子可以在互联网和文档中找到。

0 个答案:

没有答案