如何使用 Django ORM 获取按属性分组的最新条目的值?

发布于 2024-08-24 15:41:03 字数 727 浏览 9 评论 0原文

我有一个看起来有点像这样的报告模型:

class Report(models.Model):
    date = models.DateField()
    quantity = models.IntegerField()
    product_name = models.TextField()

我知道我可以通过这种方式获得一种产品去年的最后一个条目:

Report.objects.filter(date__year=2009, product_name="corn").order_by("-date")[0]

我知道我可以通过这种方式按名称对条目进行分组:

Report.objects.values("product_name")

但是我如何获得最后一个产品的数量每个产品的条目 ?我觉得我会在 SQL 中这样做(不确定,我的 SQL 生锈了):

SELECT product_name, quantity FROM report WHERE YEAR(date) == 2009 GROUP_BY product_name HAVING date == Max(date)

我的猜测是使用带有注释的 Max() 对象,但我不知道该怎么做。

目前,我通过手动添加每个产品名称的每个查询的最后一项(我无法列出不同的产品名称)来完成此操作。

I have a report model looking a bit like this:

class Report(models.Model):
    date = models.DateField()
    quantity = models.IntegerField()
    product_name = models.TextField()

I know I can get the last entry for the last year for one product this way:

Report.objects.filter(date__year=2009, product_name="corn").order_by("-date")[0]

I know I can group entries by name this way:

Report.objects.values("product_name")

But how can I get the quantity for the last entry for each product ? I feel like I would do it this way in SQL (not sure, my SQL is rusty):

SELECT product_name, quantity FROM report WHERE YEAR(date) == 2009 GROUP_BY product_name HAVING date == Max(date)

My guess is to use the Max() object with annotate, but I have no idea how to.

For now, I do it by manually adding the last item of each query for each product_name I cant list with a distinct.

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

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

发布评论

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

评论(1

颜漓半夏 2024-08-31 15:41:03

使用 Django ORM 或 SQL 并不完全是一个简单的查询。我的第一个想法就是你可能已经在做的事情;获取不同的产品和日期对,然后对每个产品和日期执行单独的查询。

year_products = Product.objects.filter(year=2009)
product_date_pairs = year_products.values('product').distinct('product'
        ).annotate(Max('date'))
[Report.objects.get(product=p['product'], date=p['date__max']) 
        for p in product_date_pairs]

但是您可以更进一步,使用 Q 运算符和一些奇特的 OR'ing 将查询计数减少到 2 而不是 N + 1。

import operator
qs = [Q(product=p['product'], date=p['date__max']) for p in product_date_pairs]
ored_qs = reduce(operator.or_, qs)
Report.objects.filter(ored_qs)

Not exactly a trivial query using either the Django ORM or SQL. My first take on it would be to pretty much what you are probably already doing; get the distinct product and date pairs and then perform individual queries for each of those.

year_products = Product.objects.filter(year=2009)
product_date_pairs = year_products.values('product').distinct('product'
        ).annotate(Max('date'))
[Report.objects.get(product=p['product'], date=p['date__max']) 
        for p in product_date_pairs]

But you can take it a step further with the Q operator and some fancy OR'ing to trim your query count down to 2 instead of N + 1.

import operator
qs = [Q(product=p['product'], date=p['date__max']) for p in product_date_pairs]
ored_qs = reduce(operator.or_, qs)
Report.objects.filter(ored_qs)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文