首页 > 解决方案 > Django ORM - 使用 PostgreSQL 在同一个表上的 GROUP BY 子查询的内部联接

问题描述

我有一个看起来像这样的表(我省略了一些列):

ID Key_ID 项目_ID 其他栏目
1 1 123456 一个
2 1 123456 b
3 2 123456 C
4 2 123456 d
5 3 654321 e
6 3 654321 F
7 4 654321 G
8 4 654321 H

使用 Django ORM,我需要得到这个查询的等价物:

SELECT * FROM table AS t
  INNER JOIN (
    SELECT MAX(ID) AS max_ID FROM table
    GROUP BY Key_ID
    WHERE Proeject_ID = 123456
  ) AS sub_query
  ON t.ID = sub_query.max_ID

我已经尝试了一些aggregateannotate组合,但我似乎无法GROUP BY在子查询中实现。如果我能做到这一点,我可以尝试.filter(id__in=<subuery_result>如此有效地使用 aSELECT ... WHERE ID IN <subquery_result虽然这INNER JOIN将是理想的,因为子查询结果可能非常大。

更新:

我使用的数据库是 PostgreSQL,并且接受的答案只适用于此。

这是实际模型:

class SystemKey(models.Model):
    # The ID (primary key) is handled by Django.

    key_id = models.PositiveIntegerField(
        help_text="Unique key ID from System."
    )

    project = models.ForeignKey(
        "core.SystemProject",
        on_delete=models.PROTECT,
        help_text="System project that this key belongs to.",
    )

    # There are a whole bunch of other properties here

    record_created = models.DateTimeField(
        auto_now_add=True,
        help_text="Date & time when this record was added in the database.",
    )

    record_updated = models.DateTimeField(
        auto_now=True,
        help_text="Date & time when this record was updated in the database.",
    )

标签: django

解决方案


您可以进行后续调用order_bydistinct在传递字段时distinct有效地实现您想要的,唯一需要注意的是这仅适用于 PostgreSQL:

SystemKey.objects.filter(project_id=123456).order_by('key_id', '-id').distinct('key_id')

基本上在这里我们选择具有不同的条目key_id,因为我们按id降序排序,所以我们只得到每个 id 最大的条目key_id


推荐阅读