【问题标题】:Django: get duplicates based on annotationDjango:根据注释获取重复项
【发布时间】:2018-04-06 15:11:42
【问题描述】:

我想根据不区分大小写的字段值获取所有重复项。

基本上就是重写这个SQL查询

SELECT count(*), lower(name)
FROM manufacturer
GROUP BY lower(name)
HAVING count(*) > 1;

使用 Django ORM。我希望这样的事情能解决问题

from django.db.models import Count
from django.db.models.functions import Lower

from myapp.models import Manufacturer


qs = Manufacturer.objects.annotate(
    name_lower=Lower('name'),
    cnt=Count('name_lower')
).filter('cnt__gt'=1)

但它当然没有用。

知道怎么做吗?

【问题讨论】:

  • Manufacturer.objects.values(name).annotate(cnt=Count('name_lower')).filter('cnt__gt'=1)
  • @SergAnuke that will not work as name_lower 不是实际列,而是来自注释
  • .annotate(name_lower=Lower('name')) .values('name_lower')

标签: python django duplicates django-annotate


【解决方案1】:

你可以试试:

qs = Manufacturer.objects.annotate(lname=Lower('name')
     ).values('lname').annotate(cnt=Count(Lower('name'))
     ).values('lname', 'cnt').filter(cnt__gt=1).order_by('lname', 'cnt')

为什么要添加order_byordering-or-order-by

sql 查询如下:

SELECT 
    LOWER("products_manufacturer"."name") AS "lname",
    COUNT(LOWER("products_manufacturer"."name")) AS "cnt"
FROM "products_manufacturer"
GROUP BY LOWER("products_manufacturer"."name")
HAVING COUNT(LOWER("products_manufacturer"."name")) > 1
ORDER BY "lname" ASC, "cnt" ASC

【讨论】:

  • 这行得通,谢谢!但是,如果 order_by('lname', 'cnt') 不是查询的一部分,则它不起作用。你知道为什么吗?另外,annotate(cnt=Count(Lower('name')) 可以简化为annotate(cnt=Count('lname')
  • annotate()values() 子句应用于查询的顺序很重要:docs.djangoproject.com/en/1.11/topics/db/aggregation/…
猜你喜欢
  • 2022-01-25
  • 2012-11-24
  • 2019-05-25
  • 2021-07-12
  • 1970-01-01
  • 2018-06-27
  • 2016-01-09
  • 2021-12-26
  • 1970-01-01
相关资源
最近更新 更多