0

试图在 Django 中通过 Postgresql 运行复杂的查询。

这些是我的模型:

class Link(models.Model):
    short_key = models.CharField(primary_key=True, max_length=8, unique=True, blank=True)
    long_url = models.CharField(max_length=150)

class Stats_links_ads(models.Model):
    link_id = models.ForeignKey(Link, related_name='link_viewed', primary_key=True)
    ad_id = models.ForeignKey(Ad, related_name='ad_viewed')
    views = models.PositiveIntegerField()
    clicks = models.PositiveIntegerField()

我想使用 Django ORM 运行一个查询,该查询将转换为如下内容:

select a.link_id, sum(a.clicks), sum (a.views), (select long_url from links_link b where b.short_key = a.link_id_id)
from links_stats_links_ads a
group by a.link_id_id;

如果我排除long_url我需要的字段,我可以运行此代码,它将起作用:

Stats_links_Ads.objects.all().values('link_id').annotate(Sum('views'), Sum('clicks'))

我不知道如何在 select 语句中添加子查询。

谢谢

4

1 回答 1

1

您可以使用Queryset的query属性查看查询背后的原始 sql 。

例如,使用 select_related 查看我的第一个答案背后的 sql,很明显生成的 sql 没有按预期运行,访问 long_url 将导致额外的查询。

拿 2

您可以使用像这样的双下划线符号来遵循关系

qs = Stats_links_ads.objects
        .values('link_id', 'link_id__long_url')
        .annotate(Sum('views'), Sum('clicks'))
str(qs.query)
'SELECT 
    "stackoverflow_stats_links_ads"."link_id_id", 
    "stackoverflow_link"."long_url", 
    SUM("stackoverflow_stats_links_ads"."clicks") AS "clicks__sum",
    SUM("stackoverflow_stats_links_ads"."views") AS "views__sum"
FROM "stackoverflow_stats_links_ads" 
    INNER JOIN "stackoverflow_link" 
    ON ("stackoverflow_stats_links_ads"."link_id_id" = "stackoverflow_link"."short_key")
GROUP BY 
    "stackoverflow_stats_links_ads"."link_id_id", 
    "stackoverflow_link"."long_url"'

我没有处理任何数据,所以我没有验证它,但 sql 看起来是正确的。

拿 1

不工作

你不能用.select_related吗?[文档]

qs = Stats_links_Ads.objects.select_related('link')
     .values('link_id').annotate(Sum('views'), Sum('clicks'))
str(qs.query)
'SELECT 
    "stackoverflow_stats_links_ads"."link_id_id", 
    SUM("stackoverflow_stats_links_ads"."clicks") AS "clicks__sum", 
    SUM("stackoverflow_stats_links_ads"."views") AS "views__sum" 
FROM "stackoverflow_stats_links_ads" 
GROUP BY "stackoverflow_stats_links_ads"."link_id_id"'
于 2013-10-28T21:37:54.917 回答