5

我试图只选择我正在查询的表的 ID,并且仍然能够指定其他列的排序。

首先,我尝试简单地做:

SELECT DISTINCT countries.id
FROM countries
...
ORDER BY province_infos.population DESC, country_infos.population ASC

那是行不通的,因为 for SELECT DISTINCTORDER BY表达式必须出现在选择列表中,并返回错误。

如果我添加province_infos.populationand country_infos.population,它可以工作,但是我会得到重复的 ID,这是我不能拥有的。

为了解决这个问题,我尝试使用DISTINCT ON()

SELECT DISTINCT ON (countries.id)
    countries.id, country_infos.population, province_infos.population
FROM countries
...
ORDER BY province_infos.population DESC, country_infos.population ASC

那给了我错误SELECT DISTINCT ON expressions must match initial ORDER BY expressions。我也不能不SELECT DISTINCT ON订购专栏。

似乎唯一可行的方法是执行以下操作:

SELECT DISTINCT ON (countries.id) 
    countries.id
FROM countries
...
ORDER BY countries.id DESC, province_infos.population DESC, country_infos.population ASC

不幸的是,我不能这样做,因为我不能按 ID 排序,因为它会扭曲其他订单的结果。似乎唯一不按 ID 排序的方法是,如果我DISTINCT从选择中删除,但我会得到重复项。

任何人都知道我该如何解决这个问题?

编辑:我省略 的...不应该是相关的,但如果你想看到:

JOIN country_infos ON country_infos.country_refer = countries.id
JOIN languages ON languages.country_refer = countries.id
JOIN provinces ON provinces.country_refer = countries.id
JOIN province_infos ON province_infos.province_refer = provinces.id
WHERE country_infos.population > 10.3
AND languages.alphabet = 'Latin'

而且我不只是想让它适用于这个特定的查询。这只是我用来解释困境的一个例子。我正在从任意数据结构中自动生成这些类型的查询。

4

2 回答 2

7

您的问题的一般答案是,在 postgresql 的 SELECT 语句中使用 DISTINCT ON (x, ...) 时,数据库按 distinct 子句中的值进行排序,以便轻松判断行是否具有不同的值(一旦它们按值排序,db只需要一次就可以删除重复项,并且只需要比较相邻的行。因此,db会强制您在distinct子句中按相同的列进行排序。

您可以通过将原始查询设为子查询来解决此问题,如下所示:

SELECT t.id FROM
  (SELECT DISTINCT ON (countries.id) countries.id
    , province_infos.population
    , country_infos.founding_date
   FROM countries
   ...
   ORDER BY countries.id, province_infos.population DESC, country_infos.founding_date  ASC 
  )t
ORDER BY t.population DESC, T.founding_date ASC
于 2018-12-01T15:14:12.123 回答
0

使用GROUP BY,像这样:

SELECT c.id
FROM countries c
...
GROUP BY c.id
ORDER BY MAX(pi.population) DESC, MAX(ci.population) ASC;

实际上,鉴于您的问题的性质,您可能想要SUM()

SELECT c.id
FROM countries c
...
GROUP BY c.id
ORDER BY SUM(pi.population) DESC, SUM(ci.population) ASC;
于 2018-11-30T22:07:02.083 回答