Ваш запрос может выглядеть примерно так:
;with C as
(
select A, B, C, D,
row_number() over(partition by A, B order by C asc) as rn1,
row_number() over(partition by A, B order by C desc) as rn2
from YourTable
)
select C1.A, C1.B, C1.D as "D at MIN(C)", C2.D as "D at MAX(C)"
from C as C1
inner join C as C2
on C1.A = C2.A and
C1.B = C2.B
where C1.rn1 = 1 and
C2.rn2 = 1
Первая часть - это общее табличное выражение (CTE) , которое инкапсулирует запрос, который можно использовать позже в основном запросе.,Он использует row_number () для перечисления строк в каждом разделе.rn1
упорядочено по C asc
, поэтому rn1 = 1
для минимального значения C
и rn2
упорядочено по C desc
, а это означает, что rn2 = 1
для максимального значения C
.Основной запрос - это два раза объединение CTE в столбцах A
и B
.Предложение where гарантирует, что мы получим только те строки, где rn1
и rn2
равны 1
.
Вот рабочий пример, в котором вместо таблицы используется переменная таблицы @T
.
declare @T table
(
A int,
B int,
C int,
D int
)
insert into @T values
(1, 1, 1, 1),
(1, 1, 3, 2),
(1, 1, 0, 4),
(1, 1, 2, 1),
(1, 2, 1, 0),
(1, 2, 0, 2),
(1, 2, 4, 5),
(2, 1, 5, 3)
;with C as
(
select A, B, C, D,
row_number() over(partition by A, B order by C asc) as rn1,
row_number() over(partition by A, B order by C desc) as rn2
from @T
)
select C1.A, C1.B, C1.D as "D at MIN(C)", C2.D as "D at MAX(C)"
from C as C1
inner join C as C2
on C1.A = C2.A and
C1.B = C2.B
where C1.rn1 = 1 and
C2.rn2 = 1