Я предлагаю вам воспользоваться row_number и PIVOT. Это может выглядеть грязно, но я думаю, что это будет хорошо работать, и это более адаптируется к различным предположениям. Например, он не предполагает, что последнее значение datetime соответствует наибольшему значению stop_seq для данной отправки.
with test_ranked(shipment_id,stop_seq,time,rankup,rankdown) as (
select
shipment_id, stop_seq, time,
row_number() over (
partition by shipment_id
order by stop_seq
),
row_number() over (
partition by shipment_id
order by stop_seq desc
)
from test
), test_extreme_times(shipment_id,tag,time) as (
select
shipment_id, 'start', time
from test_ranked where rankup = 1
union all
select
shipment_id, 'end', time
from test_ranked where rankdown = 1
)
select
shipment_id, [start], [end]
from test_extreme_times
pivot (max(time) for tag in ([start],[end])) P
order by shipment_id;
go
PIVOT на самом деле не нужен, но он удобен. Однако, обратите внимание, что MAX внутри выражения PIVOT не делает ничего полезного. Для каждого тега есть только одно значение [time], поэтому MIN будет работать так же хорошо. Синтаксис требует агрегатную функцию в этой позиции.
Приложение: Вот адаптация решения CptSkippy, которая может быть более эффективной, чем использование MIN и MAX, если у вас есть таблица поставок:
SELECT shipment_id
, (SELECT TOP 1 time
FROM test AS [b]
WHERE b.shipment_id = a.shipment_id
ORDER BY stop_seq ASC) AS [start]
, (SELECT TOP 1 time
FROM test AS [b]
WHERE b.shipment_id = a.shipment_id
ORDER BY stop_seq DESC) AS [end]
FROM shipments_table AS [a];