Что касается вашего замечания по поводу ответа Тима
, если 2019 равен нулю, мы хотим рассчитать максимум только с 2018-2013. если 2019 доступен только 2019-2014
, вы хотите мин / макс в течение 6 лет.
Самый простой способ - сначала нормализовать данные, используя UNPIVOT
, по умолчанию это удаляет NULL:
SELECT NAME, weight, yr,
Row_Number() Over (PARTITION BY NAME ORDER BY yr DESC) AS rn
FROM mytable
UNPIVOT(weight
FOR yr
IN (
y2012 as 2012
,y2013 as 2013
,y2014 as 2014
,y2015 as 2015
,y2016 as 2016
,y2017 as 2017
,y2018 as 2018
,y2019 as 2019
)
)
Затем вы применяете свою логику с помощью оконных агрегатов, чтобы получить только последние 6 лет. ,Используя row_number
, вы получите последние 6 строк
WITH cte AS
(
SELECT NAME, weight, yr,
Row_Number() Over (PARTITION BY NAME ORDER BY yr DESC) AS rn
FROM mytable
UNPIVOT(weight
FOR yr
IN (
y2012 as 2012
,y2013 as 2013
,y2014 as 2014
,y2015 as 2015
,y2016 as 2016
,y2017 as 2017
,y2018 as 2018
,y2019 as 2019
)
)
)
SELECT NAME, Min(weight), Max(weight), Min(yr), Max(yr)
FROM cte
WHERE rn BETWEEN 1 AND 6
GROUP BY NAME
Используя max
, вы получите строки за последние 6 лет (которые будут возвращать другоерезультат, если есть дополнительные NULL):
WITH cte AS
(
SELECT NAME, weight, yr,
Max(yr) Over (PARTITION BY NAME) AS maxyr
FROM mytable
UNPIVOT(weight
FOR yr
IN (
y2012 as 2012
,y2013 as 2013
,y2014 as 2014
,y2015 as 2015
,y2016 as 2016
,y2017 as 2017
,y2018 as 2018
,y2019 as 2019
)
)
)
SELECT NAME, Min(weight), Max(weight), Min(yr), Max(yr)
FROM cte
WHERE yr BETWEEN maxyr -5 AND maxyr
GROUP BY NAME
Смотрите dbfiddle