Выберите Различать в одном столбце без упорядочения по этому столбцу. - PullRequest
0 голосов
/ 01 декабря 2018

Я пытаюсь выбрать только идентификаторы таблицы, к которой я запрашиваю, и все еще могу указать порядок в других столбцах.

Сначала я попытался просто сделать:

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

Это не сработает, потому что для SELECT DISTINCT, выражения ORDER BY должны появиться в списке выбора и вернуть ошибку.

Если я добавлю province_infos.population и country_infos.population, это сработает, но затем я получаю повторяющиеся идентификаторы, которых у меня не может быть.

Чтобы решить эту проблему, я попытался использовать 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

Я, к сожалению, не могусделать это, так как я не могу заказать по идентификаторам, так как это искажает результаты других заказов.И, похоже, единственный способ не упорядочить по идентификаторам, это если я уберу 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'

И я не просто пытаюсь получитьэто работает для этого конкретного запроса.Это просто пример, который я использую, чтобы объяснить затруднительное положение.Я генерирую такие запросы автоматически из произвольной структуры данных.

Ответы [ 2 ]

0 голосов
/ 01 декабря 2018

Общий ответ на ваш вопрос заключается в том, что при использовании DISTINCT ON (x, ...) в операторе SELECT в postgresql база данных сортируется по значениям в отдельном предложении, чтобы было легко определить, имеют ли строкиотдельные значения (как только они упорядочены по значениям, для удаления дубликатов требуется всего один проход для БД, и ему нужно только сравнить соседние строки. Из-за этого БД вынуждает вас сортировать по тем же столбцам в отдельномпредложение.

Вы можете обойти эту проблему, превратив исходный запрос в подзапрос, например:

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
0 голосов
/ 01 декабря 2018

Используйте 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;
...