Рассчитать максимум значений столбцов с общим значением в другом столбце в PostgreSQL - PullRequest
1 голос
/ 18 февраля 2020

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

У меня есть следующая таблица в качестве ввода

TABLE 1:

| id    | seq    | score |
| ----- | ------ | ----- |
| UA502 | qrst   | 8.2   |
| UA502 | abcdef | 2.2   |
| UA504 | yzab   | 8.8   |
| UA504 | lmnop  | 2.8   |
| UA503 | uvwx   | 8.6   |
| UA503 | ghijk  | 2.6   |

Требуемый вывод:

| id    | seq    | score |
| ----- | ------ | ----- |
| UA502 | qrst   | 8.2   |
| UA504 | yzab   | 8.8   |
| UA503 | uvwx   | 8.6   |

Я выполняю следующий запрос WITH (max_cal c) с функцией groupby и max на выходе другого запроса WITH (union_data; TABLE 1).

max_calc as(

  select id, seq, max(score)
  from union_data
  GROUP BY id

  )

select * from max_calc
; 

Я получаю следующую ошибку:

 Query Error: error: column "union_data.seq" must appear in the GROUP BY clause or be used in an aggregate function 

Я не понимаю эту ошибку. Я группирую данные на основе общего идентификатора, а не seq. Почему я должен включить столбец "union_data.seq" в GROUPBY.

Спасибо

Ответы [ 3 ]

3 голосов
/ 18 февраля 2020

В Postgres вы можете использовать удобное расширение distinct on для этого:

select distinct on (id) u.*
from union_data u
order by id, score desc
0 голосов
/ 18 февраля 2020

Ответы, приведенные ранее, показывают, как исправить / обойти исходную ошибку. Однако они не относятся к фактическому запросу относительно причины ошибки. Итак, вернемся к исходному запросу.

  select id, seq, max(score)
  from union_data
  GROUP BY id 

Этот запрос приводит к ошибке. Причиной является то, что неагрегированный столбец seq исключен из группировки. SQL правила синтаксиса требуют, чтобы все неагрегированные столбцы в списке выбора находились в предложении «group by», когда агрегатные функции также включены в список столбцов. Вот почему Postgres имеет расширение «отличить». По сути, это позволяет обойти синтаксическое правило SQL, но это не бесплатный обед. Distinct By предъявляет свои собственные требования.

SELECT DISTINCT ON (выражение [, ...]) сохраняет только первую строку каждого набора строк, где заданные выражения оцениваются как равные. Выражения DISTINCT ON интерпретируются с использованием тех же правил, что и для ORDER BY (см. Выше). Обратите внимание, что «первая строка» каждого набора непредсказуема, если только ORDER BY не используется, чтобы гарантировать, что желаемая строка появляется первой. ... Выражения DISTINCT ON должны соответствовать крайнему левому выражению ORDER BY. Предложение ORDER BY обычно содержит дополнительные выражения, которые определяют желаемый приоритет строк в каждой группе DISTINCT ON.]

0 голосов
/ 18 февраля 2020

Ответ GMB - лучший ответ для трех столбцов (и должным образом одобренный). Если вы хотите больше агрегации, вы можете эмулировать «первую» функцию агрегации, используя массивы:

  select id,
         (array_agg(seq order by score desc))[1] as seq,
         max(score)
  from union_data
  group by id;
...