Django ORM版本的SQL COUNT(DISTINCT <column>)</column>

时间:2013-02-12 18:59:31

标签: sql django orm

我需要在简单的消息传递系统中填写一个模板,其中包含用户活动的摘要。对于每个邮件发件人,我想要发送的邮件数量和不同收件人的数量。

以下是该模型的简化版本:

class Message(models.Model):
    sender = models.ForeignKey(User, related_name='messages_from')
    recipient = models.ForeignKey(User, related_name='messages_to')
    timestamp = models.DateTimeField(auto_now_add=True)

以下是我在SQL中的表现:

SELECT sender_id, COUNT(id), COUNT(DISTINCT recipient_id)
    FROM myapp_messages
    GROUP BY sender_id;

我一直在阅读有关ORM查询中聚合的文档,虽然annotate()可以处理第一个COUNT列,但我没有看到获取COUNT(DISTINCT)结果的方法(甚至是额外的(select = {})没有工作,虽然它似乎应该)。可以将其转换为Django ORM查询,还是应该坚持使用原始SQL?

2 个答案:

答案 0 :(得分:8)

你可以确实使用distinct和count一起,如这个答案所示:https://stackoverflow.com/a/13145407/237091

在你的情况下:

SELECT sender_id, COUNT(id), COUNT(DISTINCT recipient_id)
FROM myapp_messages
GROUP BY sender_id;

会变成:

Message.objects.values('sender').annotate(
    message_count=Count('sender'),
    recipient_count=Count('recipient', distinct=True))

答案 1 :(得分:4)

from django.db.models import Count

messages = Message.objects.values('sender').annotate(message_count=Count('sender'))

for m in messages:
    m['recipient_count'] = len(Message.objects.filter(sender=m['sender']).\
                              values_list('recipient', flat=True).distinct())