简体   繁体   English

如何使用不同的标准两次使用相同的列和sql中的一个公共列

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM