Sql server 2005 SQL Server 2005值的差异

Sql server 2005 SQL Server 2005值的差异,sql-server-2005,Sql Server 2005,我有一个疑问: SELECT ID, Value FROM Table WHERE ID = (SELECT MIN(ID) FROM Table WHERE RecID = 12637) UNION SELECT ID, Value FROM Table WHERE ID = (SELECT MAX(ID) FROM Table WHERE RecID = 12637) 我想让它告诉我两个值结果之间的差异。但我也需要它只在ID不同的情况下这样做——我相信这不会成为问题,因为我相信

我有一个疑问:

SELECT ID, Value 
FROM Table 
WHERE ID = (SELECT MIN(ID) FROM Table WHERE RecID = 12637)

UNION

SELECT ID, Value 
FROM Table 
WHERE ID = (SELECT MAX(ID) FROM Table WHERE RecID = 12637)
我想让它告诉我两个值结果之间的差异。但我也需要它只在ID不同的情况下这样做——我相信这不会成为问题,因为我相信如果只有一条记录,则只返回一个结果

更新

上面显示了当前的查询结果。我正在寻找一种方法来获得2000年的结果


背后的故事我有一个表,捕捉每个条目的值。可能有1条记录或15条记录是后续修订。我想知道在第一个记录MINID和最新记录MAXID中首次报告的内容之间的区别。我不太清楚您的要求,但您可以使用EXCEPT进行集合减法。可能有一种更优雅的方法,但我认为我有一种方法。我找到第一行和最后一行,将结果合并成一行,然后进行数学运算。在只有一排的情况下,我不是100%确定你想要什么。我将其设置为左外部联接,以允许在mins中存在某些内容,而不是在maxs中,然后作为联接条件的一部分,排除匹配的ID。如果这不正确,那么就切断和MN.ID MX.ID行

若ID和VALUE都是INT-NOT-NULL,那个么一种方法就是

SELECT RecID,
       CAST(SUBSTRING(MAX(B), 6, 4) AS INT) - CAST(SUBSTRING(MIN(B), 6, 4) AS INT)
FROM   YourTable
       CROSS APPLY (SELECT CASE
                             WHEN ID < 0 THEN 0x00
                             ELSE 0x01
                           END + CAST(ID AS BINARY(4)) + CAST(VALUE AS BINARY(4))) CA(B)
GROUP  BY RecID 
或者另一种方式,由@Andriy提供,它比第一行更有效,因为它避免了排序操作

;WITH T AS
(
SELECT *,
       MIN(ID) OVER (PARTITION BY RecID) MinId,
       MAX(ID) OVER (PARTITION BY RecID) MaxId
FROM  YourTable      
)
SELECT MAX(CASE WHEN Id = MaxId THEN Value END) - MAX(CASE WHEN Id = MinId THEN Value END)
FROM T 
GROUP BY RecID

你能详细说明这个答案吗?这看起来更像是一个评论,然后是一个实际的答案。所以对于每个RecID,你想要第一次修订和最后一次修订?好吧,知道如何得到第一个和最后一个,然后你想得到它们之间的区别?没错,比林克。感谢marc_s清理了格式。我的第一个问题仍然在试图找出正确的使用方法。ID和值的数据类型是什么?谢谢,正如您所指出的,经过一些更改和附加条件,我使其正常工作。非常感谢。@wildwally-谢谢。脏一点的第一个可能会更有效,尽管我不确定我是否真的会使用它。我一直有疑问,也不确定如何验证:如果ID ASC上有索引,按ID DESC排序是否会像按ID ASC排序一样从中受益?或者这个问题一开始就有意义吗?@AndriyM-是的,通常是这样。SQL Server可以前后扫描索引。它目前不能做反向平行扫描,有时也不考虑反向扫描复合索引时,它可以做到。e、 g.IIRC是关于RecID ASC的索引,ID ASC不会用于避免按ID DESC的RecID顺序对分区进行排序。此外,如果您在ID DESC上有索引,但插入单调递增的ID,则可能会导致高度碎片化。我想知道如果将此处的行数替换为minid over PARTITION和maxid over PARTITION是否会更好,当然,案例表达是相应的,没错。我只是在说改变技术。目前,您正在从RnAsc=1的行中提取最小值。在用窗口min替换该行之后,您将从ID=MinID MinID的行中提取min值,该行通过RecID在分区上进行MinID。最大值也一样。基本上是一样的,但是如果我理解正确的话,你可以避免在相反的方向进行平行扫描。
SELECT RecID,
       CAST(SUBSTRING(MAX(B), 6, 4) AS INT) - CAST(SUBSTRING(MIN(B), 6, 4) AS INT)
FROM   YourTable
       CROSS APPLY (SELECT CASE
                             WHEN ID < 0 THEN 0x00
                             ELSE 0x01
                           END + CAST(ID AS BINARY(4)) + CAST(VALUE AS BINARY(4))) CA(B)
GROUP  BY RecID 
;WITH T AS
(
SELECT *,
       ROW_NUMBER() OVER (PARTITION BY RecID ORDER BY ID ASC) RnAsc,
       ROW_NUMBER() OVER (PARTITION BY RecID ORDER BY ID DESC) RnDesc
FROM  YourTable      
)
SELECT MAX(CASE WHEN RnDesc = 1 THEN Value END) - MAX(CASE WHEN RnAsc = 1 THEN Value END)
FROM T 
WHERE 1 IN (RnAsc, RnDesc)
GROUP BY RecID
;WITH T AS
(
SELECT *,
       MIN(ID) OVER (PARTITION BY RecID) MinId,
       MAX(ID) OVER (PARTITION BY RecID) MaxId
FROM  YourTable      
)
SELECT MAX(CASE WHEN Id = MaxId THEN Value END) - MAX(CASE WHEN Id = MinId THEN Value END)
FROM T 
GROUP BY RecID