[英]how to use same column twice with different criteria with one common column in sql
I have a table 我有一张桌子
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
I want to use 'Cost' column twice to fetch first and last inserted value in cost corresponding to each P_ID I want output as: 我想使用“Cost”列两次来获取与我希望输出的每个P_ID相对应的成本中的第一个和最后一个插入值:
P_ID First_Cost Last_Cost
101 1000 1100
102 5000 6000
103 3000 4000
;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;
In 2012 you will be able to use FIRST_VALUE()
: 在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;
You get a slightly more favorable plan if you remove the DISTINCT
and instead use ROW_NUMBER()
with the same partitioning to eliminate multiple rows with the same P_ID
: 如果删除
DISTINCT
并使用具有相同分区的ROW_NUMBER()
来消除具有相同P_ID
多个行, 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;
Why not LAST_VALUE()
, you ask? 为什么不
LAST_VALUE()
,你问? Well, it doesn't work like you might expect. 好吧,它不会像你期望的那样工作。 For more details, see the comments under the documentation .
有关更多详细信息, 请参阅文档下的注释 。
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
Admittedly, @AaronBertrand's approach is cleaner here. 不可否认,@ AaronBertrand的方法在这里更清晰。 However, this solution will work on older versions of SQL Server (that don't support CTE's or window functions), or on pretty much any other DBMS.
但是,此解决方案适用于旧版本的SQL Server(不支持CTE或窗口功能),或几乎任何其他DBMS。
Do you want first and last in terms of Min and Max, or do you want which one was entered first and which one was entered last? 你想要Min和Max的第一个和最后一个,或者你想要先输入哪一个以及最后输入哪一个? If you want Min and max you can group by.
如果你想要Min和max,你可以分组。
SELECT P_ID, MIN(Cost), MAX(Cost) FROM table_name GROUP BY P_ID SELECT P_ID,MIN(Cost),MAX(Cost)FROM table_name GROUP BY P_ID
I believe this does your thing also, just without self joins or subqueries: 我相信这也是你的事情,只是没有自我加入或子查询:
SELECT DISTINCT
P_ID
,MIN(Cost) OVER (PARTITION BY P_ID) as FirstCost
,MAX(Cost) OVER (PARTITION BY P_ID) as LastCost
FROM Table
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.