2013-06-21 49 views
2

我有這個疑問: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不同 - 我相信這不會是一個問題,因爲我相信如果只有一條記錄,只返回1個結果。

更新

ID | Value 
------------ 
100 | 23000 
110 | 25000 

當前查詢結果如上所示。我正在尋找一種方法來獲得2000年的結果。

背後的故事我有一個表格可以捕獲每個條目的值。可能有1條記錄或15條後續修訂。我想知道什麼之間的第一條記錄MIN(ID)和最新記錄MAX(ID)

+0

因此,對於每個RecID,您想要第一個修訂版本和最後一個修訂版本?那麼,知道如何獲得第一個和最後一個,那麼你想要得到他們之間的區別? – billinkc

+0

這是正確的,billinkc。 感謝marc_s清理格式。我的第一個問題仍然試圖找出正確的方式來使用它。 – wildwally

+0

「ID」和「VALUE」的數據類型是什麼? –

回答

3

如果IDVALUEINT 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 

或可替代另一種方式(少隱蔽和更強大的不斷變化的數據類型)是

;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 

或者另一種方式,@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 
+0

替代方案非常乾淨,效果很好。 – wildwally

+0

@wildwally - 謝謝。 「更髒」的第一個可能會更有效率,但我不確定我是否真的會使用它。 –

+0

我一直懷疑(並不確定如何驗證):如果有'ID ASC'上的索引,'ORDER BY ID DESC'和'ORDER BY ID ASC'一樣是否會受益? (或者問題是否有意義?) –

-2

你的要求不是很清楚,我是第一個報道的差異,但你可以用做一套減法EXCEPT

+3

你能詳細解答這個問題嗎?這似乎更像是一個評論,然後是一個實際的答案。 – Taryn

1

有可能這是一個更優雅的方式,但我認爲我有一個方法。我找到了第一行和最後一行,並將結果加在一起做出一行,然後進行數學計算。在只有一排的情況下,我不是100%確定你想要什麼。我將它作爲一個左外連接,以允許某些內容存在於分鐘中,而不是最大值,然後作爲連接條件的一部分,我排除了匹配的ID。如果這不是正確的,那麼掐斷了AND MN.ID <> MX.ID

CREATE TABLE #tmp 
(
    ID int IDENTITY(1,1) NOT NULL 
, RecID int NOT NULL 
, Value int NOT NULL 
); 

INSERT INTO 
    #tmp 
(
    RecID 
, Value 
) 
SELECT 
    AC.object_id AS RecID 
, AC.precision + AC.scale AS Value 
FROM 
    sys.all_columns AS AC; 


WITH MINS AS 
(
    -- Find the first value for all the recids 
    SELECT 
     T.RecID 
    , T.Value 
    , T.ID 
    FROM 
     #tmp T 
    WHERE 
     T.ID = 
     (
      SELECT MIN(TI.ID) AS FirstID 
      FROM #tmp TI 
      WHERE TI.RecID = T.RecID 
     ) 
) 
, MAXS AS 
(
    -- Find the last value for all the recids 
    SELECT 
     T.RecID 
    , T.Value 
    , T.ID 
    FROM 
     #tmp T 
    WHERE 
     T.ID = 
     (
      SELECT MAX(TI.ID) AS FirstID 
      FROM #tmp TI 
      WHERE TI.RecID = T.RecID 
     ) 
) 
SELECT 
    MN.RecID 
, MN.Value - COALESCE(MX.Value, 0) AS Delta 
, MN.ID AS FirstID 
    -- might not exist 
, MX.ID AS LastID 
FROM 
    MINS AS MN 
    -- Assume we don't want things that were never updated 
    LEFT OUTER JOIN 
     MAXS AS MX 
     ON MN.RecID = MX.RecID 
     AND MN.ID <> MX.ID 
; 
+0

謝謝,正如您所指出的那樣進行了一些更改,並且獲得了相應的附加條件。非常感激。 – wildwally