Select 在一列上不同,不按该列排序

Select Distinct on one column, without ordering by that column

我正在尝试 select 仅 table 我正在查询的 ID,并且仍然能够指定其他列的顺序。

首先我尝试简单地做:

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

那行不通,因为对于 SELECT DISTINCTORDER BY 表达式必须出现在 select 列表中,并且 returns 会出错。

如果我添加 province_infos.populationcountry_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 排序的方法是,如果我从 select 中删除 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'

而且我不只是试图让它为这个特定的查询工作。这只是我用来解释困境的一个例子。我正在根据任意数据结构自动生成这些类型的查询。

使用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;

你的问题的一般答案是,当在 postgresql 的 SELECT 语句中使用 DISTINCT ON (x, ...) 时,数据库按 distinct 子句中的值排序,以使其更容易判断行是否具有不同的值(一旦它们按值排序,数据库只需要一次删除重复项,并且只需要比较相邻的行。因此,数据库强制您排序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