Как я могу получить номер строки, соответствующий каждому минимуму и максимуму в таблице ниже - PullRequest
0 голосов
/ 09 июня 2018

У меня есть таблица со схемой, показанной ниже enter image description here

Для каждого идентификатора я хочу, чтобы n1 соответствовал max (h), а n2 соответствовал min (l), гдеn1 и n2 - номера строк

Expected output
id    n1    n2
1      3    10
and similar for each id   

Если максимальное или минимальное значение повторяется более одного раза, считается только первое, которое я пробовал

select n1, max(h), n2, min(l) from t group by id

Это выдает ошибку

ERROR:  column "n1" must appear in the GROUP BY clause or be used in an aggregate function

Помощь очень ценится

Ответы [ 3 ]

0 голосов
/ 09 июня 2018

Другой способ:

SELECT id, 
       min(h) as min_h,
       max(h) as max_h,
       max( case when low_rn = 1 then n1 end) as n1_for_min,
       min( case when high_rn = 1 then n1 end) as n1_for_max
FROM (
  SELECT *,
        row_number() over (partition by id order by h) as low_rn,
        row_number() over (partition by id order by h desc) as high_rn
  FROM mytable
) x 
WHERE 1 IN (low_rn, high_rn)
GROUP BY id

Демо: https://dbfiddle.uk/?rdbms=postgres_10&fiddle=35fcb41891a8a446bcb55f0a6fd0a774

0 голосов
/ 09 июня 2018

Postgres имеет очень удобную функцию first_value(), которая делает то, что вы хотите.,,почти.Единственное неудобство в том, что это оконная функция, а не аналитическая функция.Это можно решить с помощью select distinct:

select distinct id,
       first_value(n1) over (partition by id order by h desc) as n1_at_max_h,
       first_value(n2) over (partition by id order by l desc) as n2_at_max_l
from t;

Это, вероятно, самый простой способ решения этой проблемы.

Если вы предпочитаете агрегирование, вы можете использовать:

select id,
       ( array_agg(n1 order by h desc) )[1] as n1_at_max_h,
       ( array_agg(n2 order by l desc) )[1] as n2_at_max_l
from t
group by id;
0 голосов
/ 09 июня 2018

Вы можете использовать:

SELECT t.id,
       MIN(CASE WHEN t.h = sub.h1 THEN n1 END) AS n1,
       MIN(CASE WHEN t.l = sub.l1 THEN n2 END) AS n2
FROM tab_name t
JOIN (SELECT id, MAX(h) AS h1, MIN(l) AS l1
      FROM tab_name
      GROUP BY id) sub
  ON t.id = sub.id
 AND (t.h = sub.h1 OR t.l = sub.l1)
GROUP BY t.id;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...