Django/Postgres:从 DISTINCT ON 集合中选择
Django/Postgres: Choose from DISTINCT ON sets
我有这些型号:
class Product(Model):
...
class Scanning(Model):
product = ForeignKey(..)
datetime = DateTimeField(...)
...
我正在尝试对每个产品扫描一次,其中扫描是 product.scanning.all()
组中的最新产品。
s1 = (product1,01.01.1000)
s2 = (product2,01.01.1200)
s3 = (product1,01.01.1900)
s4 = (product2,01.01.1988)
s5 = (product3,01.01.2015)
s6 = (product3,01.01.1970)
会return<s4,s3,s5>
Scanning.objects.filter(product__user=u,product__active=True).distinct('product_id').order_by('datetime')
引发异常:
ProgrammingError: SELECT DISTINCT ON expressions must match initial
ORDER BY expressions LINE 1: SELECT DISTINCT ON
("productapp_scanning"."product_id") "pro...
^
如何让它发挥作用?
使用 postgres,您不能对字段执行 distinct
,除非它也是您排序的依据:
Scanning.objects.filter(product__user=u,product__active=True).distinct('product_id').order_by('product_id', 'datetime')
如果这还不够好,一种解决方案是像这样进行双重查询:
q1 = Scanning.objects.filter(product__user=u,product__active=True).values('product_id').distinct().annotate(x=Max('id'))
q2 = Scanning.objects.filter(id__in=[i["x"] for i in q1])
我有这些型号:
class Product(Model):
...
class Scanning(Model):
product = ForeignKey(..)
datetime = DateTimeField(...)
...
我正在尝试对每个产品扫描一次,其中扫描是 product.scanning.all()
组中的最新产品。
s1 = (product1,01.01.1000)
s2 = (product2,01.01.1200)
s3 = (product1,01.01.1900)
s4 = (product2,01.01.1988)
s5 = (product3,01.01.2015)
s6 = (product3,01.01.1970)
会return<s4,s3,s5>
Scanning.objects.filter(product__user=u,product__active=True).distinct('product_id').order_by('datetime')
引发异常:
ProgrammingError: SELECT DISTINCT ON expressions must match initial ORDER BY expressions LINE 1: SELECT DISTINCT ON ("productapp_scanning"."product_id") "pro... ^
如何让它发挥作用?
使用 postgres,您不能对字段执行 distinct
,除非它也是您排序的依据:
Scanning.objects.filter(product__user=u,product__active=True).distinct('product_id').order_by('product_id', 'datetime')
如果这还不够好,一种解决方案是像这样进行双重查询:
q1 = Scanning.objects.filter(product__user=u,product__active=True).values('product_id').distinct().annotate(x=Max('id'))
q2 = Scanning.objects.filter(id__in=[i["x"] for i in q1])