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 DISTINCT
,ORDER BY
表达式必须出现在 select 列表中,并且 returns 会出错。
如果我添加 province_infos.population
和 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 排序的方法是,如果我从 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
我正在尝试 select 仅 table 我正在查询的 ID,并且仍然能够指定其他列的顺序。
首先我尝试简单地做:
SELECT DISTINCT countries.id
FROM countries
...
ORDER BY province_infos.population DESC, country_infos.population ASC
那行不通,因为对于 SELECT DISTINCT
,ORDER BY
表达式必须出现在 select 列表中,并且 returns 会出错。
如果我添加 province_infos.population
和 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 排序的方法是,如果我从 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