django orm:获取具有相应其他字段值的字段的最大值

发布于 2025-01-22 15:59:57 字数 5560 浏览 0 评论 0 原文

我有这个表( counters ):

cell_id tftralacc tfnscan thtralacc thnscan datnscan date_time
13997 10 360 94 360 2022-02-22 00:00:00:00+01
13997 01 13997 0 360 0 360 0 360 2022-22-22 01:00:00 00:00+01
13997 0 360 0 360 2022-02-22 02:00:00:00+01
13997 0 360 0 360 2022-02-22 03:00:00:00+
01 13997 360 360 360 83 360 2022-22-22-22-22-22-22-22-22 044 :00:00+01
13997 0 360 2 360 2022-02-22 05:00:00:00+01
15 360 15 360 06 00:00+01
13997 360 2022-02-22 13997 1 : 07:00:00+01
13997 21 360 409 360 2022-02-22 08:00:00+01
13997 25 360 1282 360 1282 360 2022-02-22 09:00:00:00+01
13997 20 360 20 360 1201 360 2022-260 2022-2022-02-02-02-02-02-02-02-02-02-02-02-02-02-02-02-02-02-02-02-02-02-02-02-02-02-02-02-02-02-02-02-02-02-02-02-02-02-02-02-02-22-230 2022-2302 22 10:00:00+01
13997 30 360 1381 360 2022-02-22 11:00:00:00+01
13997 42 360 924 360 360 2022-02-22 12:00:00+01
14000 1 360 1 2022-22-22-22-22-22-22-22-22-22-22-22-22-22-22-22 360 360 360 360 -22 00:00:00+01
14000 0 360 0 360 2022-02-22 01:00:00:00+01
14000 1 360 0 360 2022-02-22 02:00:00:00+01
14000 0 360 2 360 2 360 2022- 02-22 03:00:00+01
14000 0 360 0 360 2022-02-22 04:00:00:00+01
14000 0 360 12 360 2022-02-22 05:00:00:00+
01 14000 3 360 4 360 4 360 4360 20222 -02-22 06:00:00+01
14000 24 360 123 360 2022-02-22 07:00:00:00+01
14000 31 31 360 374 360 2022-02-22 08:00:00+01
14000 18 360 620 360 620 360 360 360 360 360 360 2022-02-22 09:00:00+01
14000 38 360 1616 360 2022-02-22 10:00:00:00+01
14000 360 360 1410 1410 360 2022-02-22 11:00:00+01
14000 24 360 24 360 957 360 2022-02-22 12:00:00+01

我想获得最大流量的特定 date_time 值>对于每个 cell_id ,> tftralacc tfnscan thtralacc thnscan )。

我已经通过使用 annotate() group_by() django QuerySet API:

result = Counters.objects.filter(
    date_time__gte = date_start,
    date_time__lte = date_end
).annotate(
    # calculate the traffic for each row.
    traffic = Case(
        When(Q(tfnscan=0) or Q(thnscan=0), then=0),
        default = Round((F('tftralacc')*1.0/F('tfnscan')) + 
                        (F('thtralacc')*1.0/F('thnscan')), 2),
        output_field=FloatField()
    )
).order_by('cell_id').values(
    # Group by cell_id.
    'cell_id'
).order_by().annotate(
    # calculate the max traffic for the grouped Cells.
    max_traffic = Max('traffic')
)

这里显示了每个 date_time 的计算流量

我的代码成功返回了每个 cell_id 的最大流量:

cell_id max_traffic
13997 3.92
14000 4.59,

但我的目标是获得相应的 date_time 值每个最大值。这样:

Cell_ID MAX_TRAFFIC DATE_TIME
13997 3.92 2022-02-22 11:00:00:00+01
14000 4.59 2022-02-22 10:00:00+01

Cell_ID Date_time_time_time
13997 2022-22-22-22 11:00+01:00+01:00+01:00+01:00+01:00
14000 2022-02-22 10:00:00+01,

因为该最大值只是获得 date_time 而不是目标的均值。

注意:有一个问题描述了我的问题,但是它的答案是指工作解决方案,而我的问题是不可能的。

I have this Table (Counters):

cell_id tftralacc tfnscan thtralacc thnscan date_time
13997 10 360 94 360 2022-02-22 00:00:00+01
13997 0 360 0 360 2022-02-22 01:00:00+01
13997 0 360 0 360 2022-02-22 02:00:00+01
13997 0 360 0 360 2022-02-22 03:00:00+01
13997 36 360 83 360 2022-02-22 04:00:00+01
13997 0 360 2 360 2022-02-22 05:00:00+01
13997 1 360 15 360 2022-02-22 06:00:00+01
13997 11 360 159 360 2022-02-22 07:00:00+01
13997 21 360 409 360 2022-02-22 08:00:00+01
13997 25 360 1282 360 2022-02-22 09:00:00+01
13997 20 360 1201 360 2022-02-22 10:00:00+01
13997 30 360 1381 360 2022-02-22 11:00:00+01
13997 42 360 924 360 2022-02-22 12:00:00+01
14000 1 360 36 360 2022-02-22 00:00:00+01
14000 0 360 0 360 2022-02-22 01:00:00+01
14000 1 360 0 360 2022-02-22 02:00:00+01
14000 0 360 2 360 2022-02-22 03:00:00+01
14000 0 360 0 360 2022-02-22 04:00:00+01
14000 0 360 12 360 2022-02-22 05:00:00+01
14000 3 360 4 360 2022-02-22 06:00:00+01
14000 24 360 123 360 2022-02-22 07:00:00+01
14000 31 360 374 360 2022-02-22 08:00:00+01
14000 18 360 620 360 2022-02-22 09:00:00+01
14000 38 360 1616 360 2022-02-22 10:00:00+01
14000 36 360 1410 360 2022-02-22 11:00:00+01
14000 24 360 957 360 2022-02-22 12:00:00+01

I want to get the specific date_time value of the maximum traffic (which is calculated based on the the fields tftralacc, tfnscan, thtralacc and thnscan) for every cell_id.

I've managed to get this maximum value for every cell_id by using the annotate() and group_by() functions of the Django's QuerySet API:

result = Counters.objects.filter(
    date_time__gte = date_start,
    date_time__lte = date_end
).annotate(
    # calculate the traffic for each row.
    traffic = Case(
        When(Q(tfnscan=0) or Q(thnscan=0), then=0),
        default = Round((F('tftralacc')*1.0/F('tfnscan')) + 
                        (F('thtralacc')*1.0/F('thnscan')), 2),
        output_field=FloatField()
    )
).order_by('cell_id').values(
    # Group by cell_id.
    'cell_id'
).order_by().annotate(
    # calculate the max traffic for the grouped Cells.
    max_traffic = Max('traffic')
)

The calculated traffic for every date_time is demonstrated here:
enter image description here

My code successfully returns the maximum traffic for every cell_id:

cell_id max_traffic
13997 3.92
14000 4.59

But my goal is to get the Corresponding date_time value for every max value. like this:

cell_id max_traffic date_time
13997 3.92 2022-02-22 11:00:00+01
14000 4.59 2022-02-22 10:00:00+01

or

cell_id date_time
13997 2022-02-22 11:00:00+01
14000 2022-02-22 10:00:00+01

Because that max value is just a mean to get the date_time and not the goal.

Note: There is this question that describes my problem, but its answer refers to a work-around solution, which is not possible with my problem.
SO Question

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

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

发布评论

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

评论(1

温折酒 2025-01-29 15:59:57

使用 models.subquery with 加入 cell_id 字段。然后使用 querySet.annotate() max_traffic 注释子查询。最后,使用 querySet.filter()选择具有流量等于 max_traffic 的行,并使用 .distinct()删除重复行。

counters_with_traffic = Counters.objects.filter(
    date_time__gte=date_start,
    date_time__lte=date_end
).annotate(
    # calculate the traffic for each row.
    traffic=Case(
        When(Q(tfnscan=0) | Q(thnscan=0), then=0),
        default=Round((F('tftralacc') * 1.0 / F('tfnscan')) +
                      (F('thtralacc') * 1.0 / F('thnscan')), 2),
        output_field=models.FloatField()
    )
)

counters_with_max_traffic = counters_with_traffic.order_by('cell_id').values(
    # Group by cell_id.
    'cell_id'
).order_by().annotate(
    # calculate the max traffic for the grouped Cells.
    max_traffic=Max('traffic'),
).filter(cell_id=models.OuterRef("cell_id")).values("max_traffic")

result = counters_with_traffic.annotate(
    max_traffic=models.Subquery(counters_with_max_traffic),
).filter(
    traffic=models.F("max_traffic")
).values(
    "cell_id", "max_traffic", "date_time"
).distinct("cell_id", "max_traffic")

Use models.Subquery with models.OuterRef to join on cell_id field. Then use queryset.annotate() to annotate the subquery with max_traffic. Finally, use queryset.filter() to select rows that have traffic equals to max_traffic and use .distinct() to remove duplicate rows.

counters_with_traffic = Counters.objects.filter(
    date_time__gte=date_start,
    date_time__lte=date_end
).annotate(
    # calculate the traffic for each row.
    traffic=Case(
        When(Q(tfnscan=0) | Q(thnscan=0), then=0),
        default=Round((F('tftralacc') * 1.0 / F('tfnscan')) +
                      (F('thtralacc') * 1.0 / F('thnscan')), 2),
        output_field=models.FloatField()
    )
)

counters_with_max_traffic = counters_with_traffic.order_by('cell_id').values(
    # Group by cell_id.
    'cell_id'
).order_by().annotate(
    # calculate the max traffic for the grouped Cells.
    max_traffic=Max('traffic'),
).filter(cell_id=models.OuterRef("cell_id")).values("max_traffic")

result = counters_with_traffic.annotate(
    max_traffic=models.Subquery(counters_with_max_traffic),
).filter(
    traffic=models.F("max_traffic")
).values(
    "cell_id", "max_traffic", "date_time"
).distinct("cell_id", "max_traffic")
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文