2014-01-21 3 views
2

У меня есть таблицакак использовать тот же столбец дважды с различными критериями, с одной общей колонки в SQL

ID P_ID Cost 
1 101 1000 
2 101 1050 
3 101 1100 
4 102 5000 
5 102 2000 
6 102 6000 
7 103 3000 
8 103 5000 
9 103 4000 

Я хочу использовать столбец «Цена» в два раза, чтобы принести первую и последнюю вставленную значение стоимости, соответствующей каждому P_ID Я хочу выход как:

P_ID First_Cost Last_Cost 
101 1000   1100 
102 5000   6000 
103 3000   4000 
+0

Какой версии SQL Server? – RedFilter

+1

возможно что-то с группой p_id и выберите max (cost) как last_cost, min (cost) как first_cost (или что-то) – njzk2

+0

SQL server 2008 – user3220846

ответ

7
;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.

+0

Спасибо за вашу помощь .. Этот запрос отлично работает. Возможно ли создать представление с использованием этого запроса? – user3220846

+0

Да, просто снимите CREATE VIEW в начале, выньте ведущий ';' и назовите эти два столбца 'Cost' по-разному. –

+0

Спасибо большое ... Cheers – user3220846

0

вы хотите первым и последним в плане Min и Max, или вы хотите, который один был введен первый и который один был введен в прошлом? Если вы хотите Min и max, вы можете группировать их.

ВЫБРАТЬ P_ID, MIN (Cost), MAX (стоимость) FROM table_name GROUP BY p_id

+0

Я хочу, с одной стороны, в первую очередь, и какой из них был введен последним .. – user3220846

+0

У вас есть столбец Введено? Как вы определяете, что было введено первым и последним, соответственно? – Shiva

+0

@ Шива С колонкой ID я думаю? – NickyvV

3
SELECT t.P_ID, 
    SUM(CASE WHEN ID = t.minID THEN Cost ELSE 0 END) as FirstCost, 
    SUM(CASE WHEN ID = t.maxID THEN Cost ELSE 0 END) as LastCost 
FROM myTable 
JOIN (
    SELECT P_ID, MIN(ID) as minID, MAX(ID) as maxID 
    FROM myTable 
    GROUP BY P_ID) t ON myTable.ID IN (t.minID, t.maxID) 
GROUP BY t.P_ID 

Понятно, что подход @ AaronBertrand здесь чище. Однако это решение будет работать на более старых версиях SQL Server (которые не поддерживают функции CTE или окна) или практически в любой другой СУБД.

0

Я считаю, что это делает вашу вещь также, только без самого присоединяется или подзапросы:

SELECT DISTINCT 
    P_ID 
    ,MIN(Cost) OVER (PARTITION BY P_ID) as FirstCost 
    ,MAX(Cost) OVER (PARTITION BY P_ID) as LastCost 
FROM Table 
+1

Такая же проблема, как ответ @ sweaty - это становится самой низкой и самой высокой стоимостью, не первой и последней. – PinnyM

Смежные вопросы