Группировка и суммирование с использованием неагрегированных критериев для определения выбора полей - PullRequest
0 голосов
/ 08 апреля 2020

[T- SQL на MS SQL Server 2005]

Я пытаюсь сгруппировать строки из таблицы SQL, но у меня есть требование о том, как выбрать некоторые параметры столбца, а не только на основе обычных агрегатных функций. Итак например У меня есть эта таблица:

HeaderID    mold_no     pipe_no cp_date         class total_pcs total_pss run_time
----------- ----------- ------- --------------- ----- --------- --------- ---------
113149      1603        A22     2019-10-17      35    216       1         9.08
113320      1603        A22     2019-10-17      35    1         0         0.00

И я хочу сгруппировать по mold_no, pipe_no, cp_date и class.

Тем не менее, я хочу использовать значение HeaderID, которое соответствует наибольшему значению run_time.

Так что сейчас у меня есть

select MIN(HeaderID) HeaderID, MAX(mold_no) mold_no, MAX(pipe_no) pipe_no, MAX(cp_date) cp_date,
    MAX(machine) machine, MAX(class) class, SUM(total_pcs) total_pcs, SUM(total_pss) total_pss 
from MyTable
group by cp_date, machine, mold_no, pipe_no, class 

, но, конечно, это не так работать, поскольку я не могу гарантировать, что наименьшее значение HeaderID всегда будет правильным.

Как выбрать желаемое значение HeaderID на основе наибольшего значения run_time?

Ответы [ 2 ]

1 голос
/ 08 апреля 2020

Вы можете использовать CTE, вычисляя ROW_NUMBER() по убыванию значений run_time, выполняя агрегаты с оконными функциями, а затем выбирая строку с ROW_NUMBER() = 1 (так как это будет иметь максимальное значение run_time) :

WITH CTE AS (
   SELECT HeaderID, mold_no, pipe_no, cp_date, class,
          SUM(total_pcs) OVER (PARTITION BY mold_no, pipe_no, cp_date, class) AS total_pcs,
          SUM(total_pss) OVER (PARTITION BY mold_no, pipe_no, cp_date, class) AS total_pss,
          run_time,
          ROW_NUMBER() OVER (PARTITION BY mold_no, pipe_no, cp_date, class ORDER BY run_time DESC) AS rn
    FROM data
)
SELECT HeaderID, mold_no, pipe_no, cp_date, class, total_pcs, total_pss, run_time
FROM CTE
WHERE rn = 1

Вывод:

HeaderID    mold_no     pipe_no     cp_date     class   total_pcs   total_pss   run_time
113149      1603        A22         2019-10-17  35      217         1           9.08

Демонстрация по SQLFiddle

1 голос
/ 08 апреля 2020

Это не агрегация; это фильтрация. Используйте коррелированный подзапрос:

select t.*
from t
where t.run_time = (select max(t2.run_time)
                    from t t2
                    where t2.mold_no = t.mold_no and
                          t2.pipe_no = t.pipe_no and
                          t2.cp_date = t.cp_date and
                          t2.class = t.class
                  );
...