如果结果存在,则用另一个查询的结果过滤一个连接查询,而不改变外部连接表的过滤器

问题描述 投票:0回答:0

我有以下表格:

公寓

class Apartment(models.Model):    
    name = models.CharField(max_length=250, verbose_name="Apartment Name")

回顾

class Review(models.Model):
    apartment = models.ForeignKey(Apartment, on_delete=models.CASCADE, null=True)
    review = models.TextField(null=True)
    author = models.CharField(max_length=255, null=True)
    review_date = models.DateField(null=True)

回应

class Response(models.Model):
    response = models.TextField()
    review = models.ForeignKey(Review, on_delete=models.CASCADE)
    responded_on = models.DateTimeField(auto_now_add=True)
    author = models.CharField(max_length=255)

    

注意

class Note(models.Model):
    review = models.ForeignKey(Review, on_delete=models.CASCADE, null=True)
    current_user = models.IntegerField(null=True)
    modified_on = models.DateTimeField(
      auto_now=True,verbose_name='Last Modified on'
    )

未读笔记

class UnreadNote(models.Model):
    current_user = models.IntegerField(null=True)
    review = models.ForeignKey(Review, on_delete=models.CASCADE)
    note = models.ForeignKey(
      Note, on_delete=models.CASCADE, 
      verbose_name='Last Read Note'
    )
    modified_on = models.DateTimeField(
      verbose_name='Modified Date Of Last Read Note'
    )

我想将以下逻辑插入到我构建的原始查询中:

未读笔记数:

def get_note_count_by_review(self, review_id, user_id, start_date="", end_date=""):
    unread_note = UnreadNote.objects.filter(
       review_id=review_id, sysem_user=user_id
    ).order_by("-modified_on").first()
    fields = {'review_id': review_id}
    fields.update({
         'modified_on__gt': unread_note.modified_on} if unread_note 
         else {}
    )
    fields.update(
        {'review__review_date__gte': start_date, 'review__review_date__lt': end_date} 
        if start_date and end_date else {}
    )
    unread_note_count = Note.objects.filter(**fields).exclude(current_user=user_id).exclude(current_user__isnull=True).count()
    return unread_note_count

到目前为止我的原始查询:

SELECT rw.id, a.name apartment_name, p.id property_id, rw.review_date, 
un.modified_on modified_on 
FROM review rw LEFT JOIN response re ON rw.id = re.review_id 
INNER JOIN apartment a ON a.id = rw.apartment_id 
INNER JOIN note n ON n.review_id = rw.id 
AND n.current_user != 321 AND n.current_user IS NOT NULL
WHERE  rw.apartment_id IN (23, 432, 667, 123) 
AND rw.review_date BETWEEN '2023-02-01' AND '2023-04-30' AND 
GROUP BY  rw.id 
ORDER BY rw.review_date desc

上面的查询工作正常但还想在原始查询中添加方法逻辑而不改变外部表的连接和过滤器

我试过这样的事情:

SELECT rw.id, a.name apartment_name, p.id property_id, rw.review_date, 
un.modified_on modified_on 
FROM review rw LEFT JOIN response re ON rw.id = re.review_id 
INNER JOIN apartment a ON a.id = rw.apartment_id 
INNER JOIN note n ON n.review_id = rw.id 
AND n.current_user != 321 AND n.current_user IS NOT NULL 
AND modified_on > (SELECT modified_on FROM 
unread_note WHERE current_user=321 ORDER BY modified_on LIMIT 1)
WHERE  rw.apartment_id IN (23, 432, 667, 123) 
AND rw.review_date BETWEEN '2023-02-01' AND '2023-04-30' AND 
GROUP BY  rw.id 
ORDER BY rw.review_date desc

如您所见,我已经用子查询更新了原始查询,但我认为这效率不高,而且行不通。

mysql django-models django-orm
© www.soinside.com 2019 - 2024. All rights reserved.