Не знаю, как сделать сложный SQL запрос в django
У меня есть эти две модели ниже
class Category(models.Model):
id = models.AutoField(primary_key=True)
cate_id = models.CharField(max_length=16, editable=False, default=utils.generate_random_str)
name = models.CharField(max_length=64, default="")
class Record(models.Model):
id = models.AutoField(primary_key=True)
record_id = models.CharField(max_length=16, editable=False, default=utils.generate_random_str)
count = models.IntegerField(blank=True)
user = models.ForeignKey(Profile, on_delete=models.CASCADE, null=True)
А я хочу сделать SQL-запрос, отличающий cate_id и суммирующий их значения и группирующий их следующим образом:
SELECT B.name ,SUM(A.count) AS count_sum FROM app_record AS A, app_category AS B WHERE A.`user_id` = 1 AND B.cate_id IN (SELECT DISTINCT(B.cate_id) FROM app_record AS C, app_category AS D WHERE C.category_id = D.id ) AND A.category_id = B.id GROUP BY B.cate_id;
Я ожидаю, что результаты должны быть такими:
+---------+-----------+
| name | count_sum |
+---------+-----------+
| Test1 | 494 |
| Test2 | 18 |
| Test3 | 269 |
+---------+-----------+
3 rows in set (0.001 sec)
Я хочу сделать такой запрос в Django, но не смог разобраться самостоятельно. Я пробовал это, но, похоже, ничего не вышло:
Record.objects.filter(user=user).distinct().annotate(record__category_id=F('category__id')).aggregate(count_sum=Sum('count'))
Я не знаю, как это сделать, надеюсь, кто-нибудь сможет решить эту проблему. Большое спасибо.
Если вы хотите подсчитать сумму всех записей, и вам нужен агрегат, вы можете сделать это. Я не уверен, что totalcount является фактическим итогом из-за .distinct()
, поэтому если код не подходит вам, попробуйте сначала удалить .distinct()
, а затем попробовать снова. :)
Record.objects.filter(user=user)\
.distinct()\
.annotate(total_count=Count('count'))\
.aggregate(count_sum=Sum('total_count'))
Следующий код не нужен. Django автоматически включает id связанных моделей:
.annotate(record__category_id=F('category__id'))
как указано в этом документе
Получение отличных значений из полей в mysql без использования .distinct('category__id')
Record.objects.filter(user=user).values(category__id)\
.annotate(
count_ref=models.F('count')
).aggregate(
total_count=models.Sum('count_ref')
)
# maybe using just 'count' works, instead of count_ref, without the annotation. This is how I use the code, this is how it works for me.