2016-09-14 2 views
0

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

Table Data

, как вы можете видеть, что каждая единица имеет несколько строк с boxid, amnt1 и amnt2.

Что мне нужно, когда запрос выполняется, он возвращает выделенные строки, что означает, что он вернет идентификатор устройства, с boxid строки с MAX (amnt1), MAX (amnt2) среди строк групп. Таким образом, в случае блока 10002 наибольший amnt1 составляет 1,60, поэтому выход составляет

10002, 156, 1.60, 

Может ли кто-нибудь помочь мне? Я не в состоянии получить это сделано

Благодаря

ответ

1

Вот метод, который вычисляет максимальное значение для каждого столбца, а затем использует эту информацию, чтобы найти общую строку:

select t.* 
from (select t.*, 
      max(amnt1) over (partition by unit) as max1, 
      max(amnt2) over (partition by unit) as max2 
     from t 
    ) t 
where (t.amnt1 = max1 and max1 >= max2) or 
     (t.amnt2 = max2 and max2 >= max1); 

Как это работает, путем вычисления максимума для каждого из двух столбцов для каждого unit. Эти максимумы приведены в max1 и max2.

Предложение where затем говорит: Держите эту строку, если amnt1 такие же, как max1иmax1 действительно максимум. Точно так же держите строку, если amnt2 совпадает с max2иmax2 действительно является максимальным.

Решение, данное @ZLK, является более общим. Если у вас больше столбцов, логика усложняется для объяснения этого пути (да, не так уж сложно, но тогда apply будет выглядеть проще). Но для двух столбцов, apply вложенных до row_number() начинает выглядеть немного сложнее.

+0

Хорошо, я полностью понимаю ваши ответы (Gordon и ZLK) .. оба работают так Я просто посмотрю первый на линии времени, который является Гордоном. Гордон мог бы также объяснить вам свой ответ (как в терминах мирянина), а также, если вы можете указать мне на хорошие ресурсы с примерами, где я мог бы узнать больше о переделе и перегородке? Еще раз большое спасибо за ваши ответы – user1063108

1

В случае, если вы пытаетесь сравнить значения в amnt1 и amnt2, вот пример того, как вы могли бы сделать это:

DECLARE @myTable TABLE (unit INT, boxid INT, amnt1 DECIMAL(8, 4), amnt2 DECIMAL(8, 4)); 
INSERT @myTable VALUES 
     (10002, 2, 0.042, 1.53), (10002, 27, 1.25, null), (10002, 158, null, null), (10002, 63, 1.75, null) 
    , (10003, 156, 1.60, null), (10003, 2, 0.042, 1.53), (10003, 9, null, null), (10003, 19, 1.15, null) 
    , (10004, 9, null, null), (10004, 62, 2.000, 100) 
    , (10005, 69, 0.1, 6.9), (10005, 70, 0.2, 0.2), (10005, 71, 0.23, 0.69); 

SELECT unit, boxid, amnt1, amnt2 
FROM (
    SELECT unit, boxid, amnt1, amnt2, ROW_NUMBER() OVER (PARTITION BY unit ORDER BY Y DESC) R 
    FROM @myTable 
    CROSS APPLY (
     SELECT MAX(Y) 
     FROM (VALUES (amnt1), (amnt2)) X(Y)) Z(Y)) T 
WHERE R = 1; 

Здесь применяется крест: amnt1 и amnt2 и получает максимальное значение из этих двух, то, как и в случае с другим ответом, вы используете функцию номера ряда для упорядочения набора результатов (разделенного на единицу).

+0

Обратите внимание, что вы также можете использовать DENSE_RANK() или RANK(), если OP хочет привязки вместо ROW_NUMBER() – Matt

+0

Спасибо за ваш добрый ответ ZLK – user1063108

Смежные вопросы