Django:外键上的不同,然后排序

时间:2014-09-03 14:07:49

标签: python django postgresql distinct

我有两个模型,TrackPair。每个Pair都有track1track2popularity。我试图通过对的流行度(降序)得到一个有序列表,没有两对具有相同的track1。这是我到目前为止所尝试的内容:

lstPairs = Pair.objects.order_by('-popularity','track1__id').distinct('track1__id')[:iNumPairs].values_list('track1__id', 'track2__id', 'popularity')

这给了我以下错误:

ProgrammingError: SELECT DISTINCT ON expressions must match initial ORDER BY expressions

...所以我试过了:

lstPairs = Pair.objects.order_by('-popularity','track1__id').distinct('popularity', 'track1__id')[:iNumPairs].values_list('track1__id', 'track2__id', 'popularity')

这给了我重复track1__id s的条目。有谁知道解决这个问题的方法?我猜我将不得不使用raw()或类似的东西,但我不知道我是如何解决这样的问题的。我正在使用PostgreSQL作为数据库后端,因此应支持DISTINCT

2 个答案:

答案 0 :(得分:3)

首先,让我们澄清一下:DISTINCT是标准SQL,而DISTINCT ON是PostgreSQL扩展。

错误(DISTINCT ON expressions must match initial ORDER BY expressions)表示您应该修复ORDER BY条款,而不是DISTINT ON(如果您这样做,您最终会得到不同的结果,就像您一样已经经历过。)

  

DISTINCT ON表达式必须与最左边的ORDER BY表达式匹配。 ORDER BY子句通常包含其他表达式,用于确定每个DISTINCT ON组中行的所需优先级。

这将为您提供预期的结果:

lstPairs = Pair.objects.order_by('track1__id','-popularity').distinct('track1__id')[:iNumPairs].values_list('track1__id', 'track2__id', 'popularity')

在SQL中:

SELECT DISTINCT ON (track1__id) track1__id, track2__id, popularity
FROM pairs
ORDER BY track1__id, popularity DESC

可能的顺序错误。

如果您需要原始订单,可以在此处使用子查询:

SELECT *
FROM (
  SELECT DISTINCT ON (track1__id) track1__id, track2__id, popularity
  FROM pairs
  ORDER BY track1__id
  -- LIMIT here, if necessary
)
ORDER BY popularity DESC, track1__id

答案 1 :(得分:1)

请参阅documentation on distinct

首先:

  

仅在PostgreSQL上,您可以传递位置参数(* fields)以指定DISTINCT应应用的字段的名称。

你没有'指定你的数据库后端是什么,如果它不是PostrgreSQL,你就没有机会让它工作。

第二

  

指定字段名称时,必须在QuerySet中提供order_by(),order_by()中的字段必须以distinct()中的字段开头,顺序相同。

我认为你应该使用raw(),或者获得按流行度排序的整个Pairs列表,然后在Python中按track1唯一性进行过滤。