sql - 如何在sql中使用一个公共(public)列以不同的条件两次使用同一列

标签 sql sql-server sql-server-2008

我有一张 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

我想两次使用“成本”列来获取与每个 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;

在 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 - 如何在sql中使用一个公共(public)列以不同的条件两次使用同一列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21268314/

相关文章:

mysql - 使用 JOIN 查询速度慢

python - SQL 零而不是空

sql-server - 如何设置模式比较文件,以便它始终忽略特定的数据库模式?

sql - 重用表变量?

sql-server - SSIS - 如何使用结果集作为 SQL 任务的输入并获得正确的数据类型?

sql - 为什么将 SQL 查询包装在 if 语句中会显着增加其运行时间?

php - mysql 有很多表

sql - 带有 namespace 的 openxml

sql - 在 T-SQL (SQL Server 2008) 中连接到远程服务器

c# - 系统.Data.SqlClient.SqlException : login failed for user '......'