django查询的月份值

发布于 2025-01-27 03:37:50 字数 620 浏览 4 评论 0原文

我有这样的注释:它显示了一个字段的一个月

bar = Foo.objects.annotate(
    item_count=Count('item')
).order_by('-item_month', '-item_year')

,这会产生这样的输出: html渲染

我想显示与上个月的item_count的item_count的变化月(第一个月除外)。如何使用注释来实现这一目标,还是需要使用大熊猫?

谢谢

编辑: 在sql中,这与滞后函数变得容易,它类似于

SELECT item_month, item_year, COUNT(item),
LAG(COUNT(item)) OVER (ORDER BY item_month, item_year)
FROM Foo 
GROUP BY item_month, item_year

(ps:item_month和item_year是日期字段)

django orm是否与sql中的滞后相似?

I have an annotation like this: which displays the month wise count of a field

bar = Foo.objects.annotate(
    item_count=Count('item')
).order_by('-item_month', '-item_year')

and this produces output like this:
html render

I would like to show the change in item_count when compared with the previous month item_count for each month (except the first month). How could I achieve this using annotations or do I need to use pandas?

Thanks

Edit:
In SQL this becomes easy with LAG function, which is similar to

SELECT item_month, item_year, COUNT(item),
LAG(COUNT(item)) OVER (ORDER BY item_month, item_year)
FROM Foo 
GROUP BY item_month, item_year

(PS: item_month and item_year are date fields)

Do Django ORM have similar to LAG in SQL?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

囍孤女 2025-02-03 03:37:50

您需要在django orm中使用窗口函数

作为滞后

对于这些类型的查询, lag“ rel =“ nofollow noreferrer”> https://docs.djangoproject.com/en/4.0/ref/models/database-functions/#lag

ORM中的工作查询将看起来像这样:

#models.py.py.py.py.py

class Review(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='review_user', db_index=True)
    review_text = models.TextField(max_length=5000)
    rating = models.SmallIntegerField(
        validators=[
            MaxValueValidator(10),
            MinValueValidator(1),
        ],
    )
    date_added = models.DateTimeField(db_index=True)
    review_id = models.AutoField(primary_key=True, db_index=True)

这只是一个虚拟表,向您显示lagwindow函数的用例
因为Django文档上的滞后功能不可用。

from django.db.models.functions import Lag, ExtractYear
from django.db.models import F, Window

print(Review.objects.filter().annotate(
        num_likes=Count('likereview_review')
    ).annotate(item_count_lag=Window(expression=Lag(expression=F('num_likes')),order_by=ExtractYear('date_added').asc())).order_by('-num_likes').distinct().query)

查询看起来也将看起来

SELECT DISTINCT `temp_view_review`.`user_id`, `temp_view_review`.`review_text`, `temp_view_review`.`rating`, `temp_view_review`.`date_added`, `temp_view_review`.`review_id`, COUNT(`temp_view_likereview`.`id`) AS `num_likes`, LAG(COUNT(`temp_view_likereview`.`id`), 1) OVER (ORDER BY EXTRACT(YEAR FROM `temp_view_review`.`date_added`) ASC) AS `item_count_lag` FROM `temp_view_review` LEFT OUTER JOIN `temp_view_likereview` ON (`temp_view_review`.`review_id` = `temp_view_likereview`.`review_id`) GROUP BY `temp_view_review`.`review_id` ORDER BY `num_likes` DESC

像您不想在提取的日期上订购_BY,则可以使用f表达式以下

print(Review.objects.filter().annotate(
        num_likes=Count('likereview_review')
    ).annotate(item_count_lag=Window(expression=Lag(expression=F('num_likes')),order_by=[F('date_added')])).order_by('-num_likes').distinct().query)

查询:

SELECT DISTINCT `temp_view_review`.`user_id`, `temp_view_review`.`review_text`, `temp_view_review`.`rating`, `temp_view_review`.`date_added`, `temp_view_review`.`review_id`, COUNT(`temp_view_likereview`.`id`) AS `num_likes`, LAG(COUNT(`temp_view_likereview`.`id`), 1) OVER (ORDER BY `temp_view_review`.`date_added`) AS `item_count_lag` FROM `temp_view_review` LEFT OUTER JOIN `temp_view_likereview` ON (`temp_view_review`.`review_id` = `temp_view_likereview`.`review_id`) GROUP BY `temp_view_review`.`review_id` ORDER BY `num_likes` DESC

For these types of Query you need to use Window functions in django Orm

For Lag you can take the help of

https://docs.djangoproject.com/en/4.0/ref/models/database-functions/#lag

Working Query in Orm will look like this :

#models.py

class Review(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='review_user', db_index=True)
    review_text = models.TextField(max_length=5000)
    rating = models.SmallIntegerField(
        validators=[
            MaxValueValidator(10),
            MinValueValidator(1),
        ],
    )
    date_added = models.DateTimeField(db_index=True)
    review_id = models.AutoField(primary_key=True, db_index=True)

This is just a dummy table to show you the use case of Lag and Window function in django
Because examples are not available for Lag function on Django Docs.

from django.db.models.functions import Lag, ExtractYear
from django.db.models import F, Window

print(Review.objects.filter().annotate(
        num_likes=Count('likereview_review')
    ).annotate(item_count_lag=Window(expression=Lag(expression=F('num_likes')),order_by=ExtractYear('date_added').asc())).order_by('-num_likes').distinct().query)

Query will look like

SELECT DISTINCT `temp_view_review`.`user_id`, `temp_view_review`.`review_text`, `temp_view_review`.`rating`, `temp_view_review`.`date_added`, `temp_view_review`.`review_id`, COUNT(`temp_view_likereview`.`id`) AS `num_likes`, LAG(COUNT(`temp_view_likereview`.`id`), 1) OVER (ORDER BY EXTRACT(YEAR FROM `temp_view_review`.`date_added`) ASC) AS `item_count_lag` FROM `temp_view_review` LEFT OUTER JOIN `temp_view_likereview` ON (`temp_view_review`.`review_id` = `temp_view_likereview`.`review_id`) GROUP BY `temp_view_review`.`review_id` ORDER BY `num_likes` DESC

Also if you don't want to order_by on extracted year of date then you can use F expressions like this

print(Review.objects.filter().annotate(
        num_likes=Count('likereview_review')
    ).annotate(item_count_lag=Window(expression=Lag(expression=F('num_likes')),order_by=[F('date_added')])).order_by('-num_likes').distinct().query)

Query for this :

SELECT DISTINCT `temp_view_review`.`user_id`, `temp_view_review`.`review_text`, `temp_view_review`.`rating`, `temp_view_review`.`date_added`, `temp_view_review`.`review_id`, COUNT(`temp_view_likereview`.`id`) AS `num_likes`, LAG(COUNT(`temp_view_likereview`.`id`), 1) OVER (ORDER BY `temp_view_review`.`date_added`) AS `item_count_lag` FROM `temp_view_review` LEFT OUTER JOIN `temp_view_likereview` ON (`temp_view_review`.`review_id` = `temp_view_likereview`.`review_id`) GROUP BY `temp_view_review`.`review_id` ORDER BY `num_likes` DESC
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文