【问题标题】:How to limit annotated queries to a single column in Django's ORM?如何将带注释的查询限制为 Django ORM 中的单个列?
【发布时间】:2020-12-09 03:39:09
【问题描述】:

我有一个表映射(id, key, value),我想从中选择具有相同值的键。在 SQL 中我可以做

SELECT key FROM map WHERE value IN (SELECT value FROM map GROUP BY value HAVING COUNT(*) > 1);

我试着把它翻译成 Django 的 ORM 风格

from django.db.models import Count

Map.objects.filter(value__in=Map.objects.values('value').annotate(count=Count('value')).filter(count__gt=1)).values('key')

但它失败了,因为__in 过滤器中的子查询返回两列,选定的value 列和计数列:

SELECT "map"."key" FROM "map" WHERE "map"."value" IN (SELECT U0."value", COUNT(U0."value") AS "count" FROM "map" U0 GROUP BY U0."value" HAVING COUNT(U0."value") > 1)

如何从该子查询中删除不需要的 count 列?

【问题讨论】:

  • 您是否尝试过使用Subquery 执行此操作? docs.djangoproject.com/en/3.1/ref/models/expressions/…
  • @markwalker_ 将子查询限制为单个列是我想要的,但.values() 不会将注释限制为单个列,除非该列是注释本身。此外,__in 过滤器中的查询是一个隐式子查询,django 会内联它。

标签: python mysql django


【解决方案1】:

你多加一个.values(…) [Django-doc]:

from django.db.models import Count

Map.objects.filter(
    value__in=Map.objects.values('value').annotate(
        count=Count('value')
    ).filter(count__gt=1).order_by('value').values('value')
).values('key')

.order_by(…) [Django-doc] 部分是从 GROUP BY 子句中删除 .id 所必需的。

【讨论】:

  • 不需要 order_by 查询,最后附加的.values() 过滤器解决了它:SELECT "map"."key" FROM "map" WHERE "map"."value" IN (SELECT U0."value" FROM "map" U0 GROUP BY U0."value" HAVING COUNT(U0."value") > 1)。谢谢。
猜你喜欢
  • 2019-10-13
  • 2018-04-11
  • 2019-08-03
  • 2014-08-09
  • 1970-01-01
  • 2020-01-26
  • 2018-08-26
  • 1970-01-01
  • 2020-05-14
相关资源
最近更新 更多