【发布时间】:2020-08-14 07:17:29
【问题描述】:
我想汇总使用相同视频资源的工作计数,以及基于不同用户数的用户计数。为此我尝试了两种方法,但结果相互矛盾。
问题是:我的代码中的两个 qset 结果不一样。 qset1 是正确的,但是 qset2 是错误的,因为它没有排除相同的用户。
我的问题:如果我不想像 qset1 那样使用 RawSQL,并且想要正确的结果,我该怎么办?
我的代码如下:
#models concerned
class Video(models.Model):
name = models.CharField(max_length=100, verbose_name=_('video name'))
class Work(models.Model):
video = models.ForeignKey(Video, on_delete=models.CASCADE, related_name='works_of_video', verbose_name=_('video'))
maker = models.ForeignKey(User, on_delete=models.CASCADE, related_name='works_of_maker', verbose_name=_('maker'))
class ShareRecord(models.Model):
work = models.ForeignKey(Work, on_delete=models.CASCADE, related_name='share_records_of_work', verbose_name=_('work shared'))
sharer = models.ForeignKey(User, on_delete=models.CASCADE, related_name='share_records_of_sharer', verbose_name=_('sharer'))
share_date = models.DateField(default=timezone.now, verbose_name=_('share date'))
#rawsql for get_queryset()
video_sql = u'''SELECT COUNT(*) AS "num"
From (SELECT DISTINCT maker_id
FROM "video_manage_work" U0
INNER JOIN "video_manage_demouser" U2 ON (U0."maker_id" = U2."id")
WHERE (U0."video_id" = ("video_manage_video"."id") AND U2."gender" IN (%s))
)'''
#views concerned
def get_queryset(request):
what_gender = (0, 1)
vall = Video.object.all()
works = Work.objects.filter(video=OuterRef('pk')).filter(maker__gender__in=what_gender)
works_makers = works.values('maker','video').distinct()
# the next annotate use RawSQL of video_sql
qset1 = vall.annotate(works_num=Subquery(works.values('video').annotate(num=Count('*')).values('num'), output_field=IntegerField()))\
.annotate(makers_num=RawSQL(video_sql, (gender_str,)))
# the next annotate use Subquery that try to distinct queryset that excluded the same users
qset2 = vall.annotate(works_num=Subquery(works.values('video').annotate(num=Count('*')).values('num'), output_field=IntegerField()))\
.annotate(makers_num=Subquery(works_makers.values('video').annotate(num=Count('*')).values('num'), output_field=IntegerField()))
return render(request, 'video_manage/video_data.html')
'''
######sql sentenc of qset2 created by django:
SELECT "video_manage_video"."id",
"video_manage_video"."name",
(SELECT COUNT(*) AS "num"
FROM "video_manage_work" U0
INNER JOIN "video_manage_demouser" U2 ON (U0."maker_id" = U2."id")
WHERE (U0."video_id" = "video_manage_video"."id"
AND U2."gender" IN (0,
1))
GROUP BY U0."video_id") AS "works_num",
(SELECT COUNT(*) AS "num"
From (SELECT DISTINCT maker_id
FROM "video_manage_work" U0
INNER JOIN "video_manage_demouser" U2 ON (U0."maker_id" = U2."id")
WHERE (U0."video_id" = ("video_manage_video"."id")
AND U2."gender" IN (0,
1))
)
) AS "makers_num"
FROM "video_manage_video";
'''
【问题讨论】:
标签: django subquery django-queryset distinct