;WITH t AS
(
SELECT P_ID, Cost,
f = ROW_NUMBER() OVER (PARTITION BY P_ID ORDER BY ID),
l = ROW_NUMBER() OVER (PARTITION BY P_ID ORDER BY ID DESC)
FROM dbo.tablename
)
SELECT t.P_ID, t.Cost, t2.Cost
FROM t INNER JOIN t AS t2
ON t.P_ID = t2.P_ID
WHERE t.f = 1 AND t2.l = 1;
В 2012 году вы будете иметь возможность использовать FIRST_VALUE()
:
SELECT DISTINCT
P_ID,
FIRST_VALUE(Cost) OVER (PARTITION BY P_ID ORDER BY ID),
FIRST_VALUE(Cost) OVER (PARTITION BY P_ID ORDER BY ID DESC)
FROM dbo.tablename;
Вы получаете немного больше благоприятный план, если вы удалите DISTINCT
и вместо этого используйте ROW_NUMBER()
с тем же перегородкой, чтобы устранить несколько рядов с одинаковыми P_ID
:
;WITH t AS
(
SELECT
P_ID,
f = FIRST_VALUE(Cost) OVER (PARTITION BY P_ID ORDER BY ID),
l = FIRST_VALUE(Cost) OVER (PARTITION BY P_ID ORDER BY ID DESC),
r = ROW_NUMBER() OVER (PARTITION BY P_ID ORDER BY ID)
FROM dbo.tablename
)
SELECT P_ID, f, l FROM t WHERE r = 1;
Почему не LAST_VALUE()
, спросите вы? Ну, это не работает, как вы могли бы ожидать. Для получения более подробной информации, see the comments under the documentation.
Какой версии SQL Server? – RedFilter
возможно что-то с группой p_id и выберите max (cost) как last_cost, min (cost) как first_cost (или что-то) – njzk2
SQL server 2008 – user3220846