我正在使用带有PostgreSQL的Django 1.6并拥有以下模型:
# models.py
class Game(AbstractContentModel, AbstractScoreModel):
name = models.CharField(_("name"), max_length=100, blank=True)
developer = models.CharField(_('Developer'), max_length=255)
distributor = models.CharField(_('Distributor'), max_length=255, blank=True)
# ...
reviews = models.ManyToManyField(Review, related_name="games", blank=True, verbose_name=_("Reviews"))
videos = models.ManyToManyField(Video, related_name="games", blank=True, verbose_name=_("Videos"))
images = models.ManyToManyField(Image, related_name="games", blank=True, verbose_name=_("Gallery"))
我试图获取所有游戏,并且每个游戏都会添加相关视频,评论和图片,如下所示:
# views.py
qs = Game.objects.all()
qs = qs.annotate(video_count=models.Count('videos'))
qs = qs.annotate(review_count=models.Count('reviews'))
qs = qs.annotate(image_count=models.Count('images'))
结果查询是:
SELECT
"content_game"."id",
"content_game"."name",
"content_game"."developer",
"content_game"."distributor",
COUNT("content_game_videos"."video_id") AS "video_count",
COUNT("content_game_reviews"."review_id") AS "review_count",
COUNT("content_game_images"."image_id") AS "image_count"
FROM "content_game"
LEFT OUTER JOIN "content_game_videos" ON ( "content_game"."id" = "content_game_videos"."game_id" )
LEFT OUTER JOIN "content_game_reviews" ON ( "content_game"."id" = "content_game_reviews"."game_id" )
LEFT OUTER JOIN "content_game_images" ON ( "content_game"."id" = "content_game_images"."game_id" )
GROUP BY
"content_game"."id",
"content_game"."name",
"content_game"."developer",
"content_game"."distributor";
我的问题是 - 为什么GROUP BY子句中有所有选定的字段?最重要的是,除了原始SQL之外,我怎么能摆脱它们?
我认为使用.values()
会很好,但我希望结果查询中的每个字段。如果我只使用GROUP BY "content_game"."id"
,结果是一样的,但我不知道如何使用Django ORM这样使用它。
答案 0 :(得分:1)
我来不及回答,但我有点研究答案。首先,OP所说的行为是正确的。并且它应该适用于所有类型的关系数据库,但正如@ lad2025在评论中所说的那样,唯一的MySQL(MariaDB也是如此)就是这种行为。因此,我们必须学习它,而不是摆脱它。因为这是使用它/理解它并习惯它的唯一正确方法。
目前OP找到了解决方法,即继续更新表字段的行数,并在以后填充而不是 通过查询动态检索数据。
在使用聚合函数时,无论你添加到GROUP BY中的任何内容都必须包含在SELECT中,反之亦然。
return_sequences=False
上面的字段必须进入GROUP BY,因为如果我尝试打印id或任何字段,从选择哪一行的字段(单个)值返回?组群中的最后一行或第一行是不正确的(MySQL会这样做)。所以最好把所有人都留进GROUP BY。
为什么呢?由于含糊不清 - "content_game"."id", "content_game"."name", "content_game"."developer", "content_game"."distributor"
为每组记录生成一条记录。 group by
列包含组中所有记录的相同值,并且任何聚合函数都会为组生成单个值,但Group By
组的"content_game"."developer"
可能不同
"content_game"."distributor"
对于所有行都是不同的,因为它是主键。所有领域都相同。
可以找到好的解释here
我希望人们以更好的方式分享(编辑我的帖子)更多声明。所以其他人可以在将来发现它很有用。