我有一张桌子
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 :(得分: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。
答案 1 :(得分: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或窗口功能),或几乎任何其他DBMS。
答案 2 :(得分:0)
你想要Min和Max的第一个和最后一个,或者你想要先输入哪一个以及最后输入哪一个?如果你想要Min和max,你可以分组。
SELECT P_ID,MIN(Cost),MAX(Cost)FROM table_name GROUP BY P_ID
答案 3 :(得分: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