【问题标题】:Django query api: complex subqueryDjango 查询 api:复杂子查询
【发布时间】:2017-10-08 13:17:50
【问题描述】:

我浪费了很多时间来编写这样的查询。这是我的模型:

class User(Dealer):
    pass


class Post(models.Model):
    text = models.CharField(max_length=500, default='')
    date = models.DateTimeField(default=timezone.now)
    interactions = models.ManyToManyField(User, through='UserPostInteraction', related_name='post_interaction')


class UserPostInteraction(models.Model):
    post = models.ForeignKey(Post, related_name='pppost')
    user = models.ForeignKey(User, related_name='uuuuser')
    status = models.SmallIntegerField()


    DISCARD = -1
    VIEWED = 0
    LIKED = 1
    DISLIKED = 2

我需要什么:

子查询是:(UserPostInteractions where status = LIKED) - (UserPostInteractions where status = DISLIKED) of Post(OuterRef('pk'))

查询是:Select all posts order by value of subquery

我遇到了错误Subquery returned multiple rows

埃尔普!!))

【问题讨论】:

  • 你的目标不是很清楚,试着澄清你的需求。另外 - 您产生错误的实际尝试将有助于更好地了解您。

标签: python sql django


【解决方案1】:

如果我正确理解你的需求,你可以通过这样的 qs 得到你所需要的:

from django.db.models import Case, Sum, When, IntegerField

posts = Post.objects.values('id', 'text', 'date').annotate(
    rate=Sum(Case(
        When(pppost__status=1, then=1), 
        When(pppost__status=2, then=-1), 
        default=0, 
        output_field=IntegerField()
    ))
).order_by('rate')

在 MySql 中它转换为这样的 sql 查询:

SELECT
  `yourapp_post`.`id`,
  `yourapp_post`.`text`,
  `yourapp_post`.`date`,
  SUM(
      CASE
        WHEN `yourapp_userpostinteraction`.`status` = 1
          THEN 1
        WHEN `yourapp_userpostinteraction`.`status` = 2
          THEN -1
        ELSE 0
      END) AS `rate`
FROM `yourapp_post`
  LEFT OUTER JOIN `yourapp_userpostinteraction` ON (`yourapp_post`.`id` = `yourapp_userpostinteraction`.`post_id`)
GROUP BY `yourapp_post`.`id`
ORDER BY `rate` ASC

【讨论】:

    猜你喜欢
    • 2011-06-08
    • 2012-10-25
    • 1970-01-01
    • 2016-09-07
    • 1970-01-01
    • 1970-01-01
    • 2014-12-22
    • 2011-10-20
    相关资源
    最近更新 更多