Нужен оператор SQL для возврата MAX вычисленного значения, сгруппированного по общим кодам - PullRequest
1 голос
/ 25 марта 2020

Я искал ответ на проблему, но не могу найти тот, который точно соответствует тому, что мне нужно.

У меня есть SQL база данных с несколькими столбцами. Данные выглядят так:

Code    Time  Field_x   Field_y
--------------------------------    
Code1     0      100        50
Code1     1      123        83
Code1     2       85       112
Code1     3       74       300
Code2     0      120        52
Code2     2       12        41
Code2     4      340         0
Code3     1.2    100        50
Code3     3       45       111
Code3     5       66       -41
Code3     6.3    300       105

et c.

Field_1 и Field_2 используются для вычисления значения. Они находятся в одной таблице.

Computed = 0.34*Field_1 + -0.65*Field_2

Те же 0,34 и -0,65 используются для каждого набора значений Code (i).

Что я хотел бы получить в этом примере, будет 3 строки результатов, которые будут временем и значением, связанным с максимальным вычисленным значением каждой группы. Таким образом, код1 будет иметь результат, код2 - результат, код3 и т. Д. c.

В этом коротком примере результаты будут такими:

Code1    0      1.50
Code2    4    115.60
Code3    5     49.09

Я думал, что это будет так же просто, как

SELECT 
    Time, MAX(0.34 * Field_1 + -0.65 * Field_2) 
FROM 
    Table  
GROUP BY 
    Code

, но я получаю сообщение о том, что не могу использовать MAX таким образом.

Спасибо за любую помощь!

1 Ответ

0 голосов
/ 25 марта 2020

Использовать оконные функции:

select t.*
from (select t.*,
             (0.34*Field_1 + -0.65*Field_2) as computed_value,
             row_number() over (partition by code order by (0.34*Field_1 + -0.65*Field_2) desc) as seqnum
      from t
     ) t
where seqnum = 1;

Примечание. Если для данного кода есть связи для максимума, возвращается произвольная строка. Если вы хотите, чтобы все строки имели максимум, используйте rank() вместо row_number().

РЕДАКТИРОВАТЬ:

Для максимума и минимума просто используйте два порядковых номера:

select t.*
from (select t.*,
             (0.34*Field_1 + -0.65*Field_2) as computed_value,
             row_number() over (partition by code order by (0.34*Field_1 + -0.65*Field_2) desc) as seqnum_max,
             row_number() over (partition by code order by (0.34*Field_1 + -0.65*Field_2) asc) as seqnum_min
      from t
     ) t
where 1 in (seqnum_min, seqnum_max);
...