Annotate + Distinct Not Implemented,算一个Distinct子查询
Annotate + Distinct Not Implemented, Count a Distinct Subquery
我有两个模型,RetailLocation 和 Transaction,它们分别共享一对多关系。我试图注释 RetailLocation 有任意数量的交易的总天数(计数)。在这样做时,我将 Transaction.date 字段过滤为日期而不是日期时间,并尝试 SELECT DISTINCT 日期,但 运行 进入错误“NotImplementedError: annotate() + distinct(fields) 未实现。"
型号
class RetailLocation(models.Model):
name = models.CharField(max_length=200, null=True)
class Transaction(models.Model):
date = models.DateTimeField(null=True)
r_loc = models.ForeignKey(RetailLocation, null=True, on_delete=models.SET_NULL)
尝试的代码
test = RetailLocation.objects.annotate(
days_operating=Subquery(
Transaction.objects.filter(r_loc=OuterRef("pk"))
.distinct('date__date')
.annotate(count=Count('pk'))
.values('count')
)
)
in combination with ,但使用 distinct 似乎会导致上面提到的 NotImplementedError。我相信也可能有一个使用 Count( , distinct=True) 的解决方案,但它不会有帮助,除非我可以在 date__date 上区分,因为我只是想找到发生任意数量事务的日期。
非常感谢您抽出宝贵时间。
方案一(使用外键)
RetailLocation.objects.annotate(days_operating=Count('transaction__date__date', distinct=True))
使用 RetailLocation 和 Transaction 之间的 ForeignKey 关系,首先按照 ForeignKey 获取相关的 Transaction 对象集 ('transaction'),然后 select 'date' 列 ('transaction_date'),最后将其转换为日期 ('transaction_date_date')。 returns 字典列表 {date_date: 日期对象},并使用 Count( , distinct=True) 计算唯一日期集。
解决方案 2(使用子查询)
test = RetailLocation.objects.annotate(
days_operating=Subquery(
Transaction.objects.filter(r_loc=OuterRef("pk"))
.values('r_loc')
.annotate(count=Count('date__date', distinct=True))
.values('count')
)
)
这与解决方案 1 的工作方式基本相同,但如果您想根据其他内容进行过滤,则 不需要 在两个模型之间建立外键关系 (也许是日期)。
我有两个模型,RetailLocation 和 Transaction,它们分别共享一对多关系。我试图注释 RetailLocation 有任意数量的交易的总天数(计数)。在这样做时,我将 Transaction.date 字段过滤为日期而不是日期时间,并尝试 SELECT DISTINCT 日期,但 运行 进入错误“NotImplementedError: annotate() + distinct(fields) 未实现。"
型号
class RetailLocation(models.Model):
name = models.CharField(max_length=200, null=True)
class Transaction(models.Model):
date = models.DateTimeField(null=True)
r_loc = models.ForeignKey(RetailLocation, null=True, on_delete=models.SET_NULL)
尝试的代码
test = RetailLocation.objects.annotate(
days_operating=Subquery(
Transaction.objects.filter(r_loc=OuterRef("pk"))
.distinct('date__date')
.annotate(count=Count('pk'))
.values('count')
)
)
非常感谢您抽出宝贵时间。
方案一(使用外键)
RetailLocation.objects.annotate(days_operating=Count('transaction__date__date', distinct=True))
使用 RetailLocation 和 Transaction 之间的 ForeignKey 关系,首先按照 ForeignKey 获取相关的 Transaction 对象集 ('transaction'),然后 select 'date' 列 ('transaction_date'),最后将其转换为日期 ('transaction_date_date')。 returns 字典列表 {date_date: 日期对象},并使用 Count( , distinct=True) 计算唯一日期集。
解决方案 2(使用子查询)
test = RetailLocation.objects.annotate(
days_operating=Subquery(
Transaction.objects.filter(r_loc=OuterRef("pk"))
.values('r_loc')
.annotate(count=Count('date__date', distinct=True))
.values('count')
)
)
这与解决方案 1 的工作方式基本相同,但如果您想根据其他内容进行过滤,则 不需要 在两个模型之间建立外键关系 (也许是日期)。