Как выбрать максимум одного столбца для другого столбца - PullRequest
1 голос
/ 29 июня 2019

Я использую SQL Server и у меня есть таблица "a"

month  segment_id   price
-----------------------------
  1      1            100       
  1      2            200     
  2      3             50     
  2      4             80      
  3      5             10 

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

Результат должен быть:

month  segment_id   price
----------------------------     
  1      2            200        
  2      4             80      
  3      5             10 

Я пытался написать код SQL:

Select 
    month, segment_id, max(price) as MaxPrice
from 
    a

но я получил ошибку:

Столбец сегмент_ид недопустим в списке выбора, поскольку он не содержится ни в статистической функции , ни в предложении GROUP BY

Я пытался исправить это разными способами, но не нашел, как это исправить

Спасибо за помощь,

John

Ответы [ 4 ]

3 голосов
/ 29 июня 2019

Поскольку вам нужно сгруппировать предложение без сегмента_иде

Select month, max(price) as MaxPrice 
  from a
 Group By month

, так как вы хотите получать результаты за каждый месяц, а сегмент_ид не агрегируется в исходном операторе выбора.

Если вы хотитедля того, чтобы сегмент_ид с ​​повторением максимальной цены за каждый месяц для каждой строки, необходимо использовать функцию max () в качестве аналитической функции окна без условия группировки по пункту

Select month, segment_id, 
       max(price) over ( partition by month order by segment_id ) as MaxPrice 
  from a

Редактировать (из-за вашегонаконец отредактировал желаемые результаты) : вам нужна еще одна аналитическая функция окна row_number(), как уже упоминал @Gordon:

Select month, segment_id, price From
(
Select a.*,
       row_number() over ( partition by month order by price desc ) as Rn
  from a
  ) q
Where rn = 1 
1 голос
/ 29 июня 2019

Только потому, что не было упомянуто.

Еще одним вариантом является предложение WITH TIES .

Чтобы было ясно , подход Гордона и Барбароса был бы более продуктивным, но этот метод не требует или генерирует дополнительный столбец.

Select Top 1 with ties *
 From  YourTable 
 Order By row_number() over (partition by month order by price desc)
1 голос
/ 29 июня 2019

Я бы порекомендовал коррелированный подзапрос:

select t.*
from t
where t.price = (select max(t2.price) from t t2 where t2.month = t.month);

«Каноническим» решением является использование row_number():

select t.*
from (select t.*,
             row_number() over (partition by month order by price desc) as seqnum
      from t
     ) t
where seqnum = 1;

При правильных индексах коррелированный подзапрос часто работает лучше.

0 голосов
/ 29 июня 2019

С not exists:

select t.*
from tablename t
where not exists (
  select 1 from tablename
  where month = t.month and price > t.price
)

или:

select t.*
from tablename inner join (
  select month, max(price) as price 
  from tablename 
  group By month
) g on g.month = t.month and g.price = t.price
...