Джанго: .annotate возвращает неожиданные результаты - PullRequest
1 голос
/ 21 июня 2019

В настоящее время у меня есть два набора запросов:

(
Event.objects.filter(organizer=1)
.values('pk', 'organizer')
.annotate(
    sold_tickets=Count('attendees', filter=Q(attendees__canceled=False))
)
.order_by('organizer')
)


(
Event.objects.filter(organizer=1)
.values('pk', 'organizer')
.annotate(available_tickets=Coalesce(Sum('tickets__quantity'), 0))
.order_by('organizer')
)

Результаты:

<EventQuerySet [{'pk': 6, 'organizer': 1, 'sold_tickets': 1}, {'pk': 1, 'organizer': 1, 'sold_tickets': 529}, {'pk': 5, 'organizer': 1, 'sold_tickets': 1}, {'pk': 4, 'organizer': 1, 'sold_tickets': 2}]>
<EventQuerySet [{'pk': 1, 'organizer': 1, 'available_tickets': 1721}, {'pk': 4, 'organizer': 1, 'available_tickets': 30}, {'pk': 5, 'organizer': 1, 'available_tickets': 10}, {'pk': 6, 'organizer': 1, 'available_tickets': 20}]>

Теперь моя идея состояла в том, чтобы объединить их.Однако я всегда получаю неожиданные и неправильные числа в своем запросе:

(
Event.objects.filter(organizer=1)
.values('pk', 'organizer')
.annotate(
    available_tickets=Coalesce(Sum('tickets__quantity'), 0),
    sold_tickets=Count('attendees', filter=Q(attendees__canceled=False))
)

.order_by('organizer')
)

Вот результат

<EventQuerySet [{'pk': 6, 'organizer': 1, 'available_tickets': 20, 'sold_tickets': 2}, {'pk': 1, 'organizer': 1, 'available_tickets': 1765746, 'sold_tickets': 2116}, {'pk': 5, 'organizer': 1, 'available_tickets': 10, 'sold_tickets': 1}, {'pk': 4, 'organizer': 1, 'available_tickets': 60, 'sold_tickets': 4}]>

Есть ли что-то в .annotate, чего я не понимаю?

1 Ответ

2 голосов
/ 21 июня 2019

Кажется, раньше у меня была такая же проблема, но я не уверен, что это именно ваша. Попробуйте добавить distinct=True к вашему annotate, которое должно быть:

.annotate(
    available_tickets=Coalesce(Sum('tickets__quantity'), 0)
).annotate(
    sold_tickets=Count('attendees', filter=Q(attendees__canceled=False), distinct=True)
)

Или вы можете попробовать добавить .distinct() так:

.annotate(
    available_tickets=Coalesce(Sum('tickets__quantity'), 0),
    sold_tickets=Count('attendees', filter=Q(attendees__canceled=False))
).distinct('available_tickets','sold_tickets')

Вот что я нашел в своем решении: https://docs.djangoproject.com/en/dev/topics/db/aggregation/#combining-multiple-aggregations

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...