2015-11-17 58 views
0

我有這個數據。最後一個ID在

  • 列A是行號
  • 列B爲母體(A)參考。

有兩組。

  • 0列b表示新組,A表示頂部元素。

如何從每個組中找到最大A?

比方說:

如果我選擇A = 3函數必需返回4,
或者如果我選擇A = 6函數返回8

a | b 
------ 
1 | 0 <- for A = 1 return 4 
2 | 1 <- for A = 2 return 4 
3 | 2 <- for A = 3 return 4 
4 | 3 <- for A = 4 return 4 
5 | 0 <- for A = 5 return 8 
6 | 5 <- for A = 6 return 8 
7 | 5 <- for A = 7 return 8 
8 | 7 <- for A = 8 return 8 
9 | 0 
+0

如果兩組具有相同的「max」值,該怎麼辦?也標記正在使用的數據庫。 –

+0

hi標記已更新:-)每個組只有一個最大ID,如果這兩個組具有相同的最大ID,則無關緊要。 – gips

+0

您能否更多地瞭解該功能應該做什麼?我沒有跟隨正在發生的事情。 – LDMJoe

回答

0

現在我明白了。訂單很重要,你想玩Cliffhangers。如果您使用的是SQL Server 2012或更高版本,但是您標記爲2008,那麼這將是LEAD()函數的一個奇妙應用程序,所以......該死。

因此,沒有LEAD(),但我們仍然有選擇。這裏有一個函數可以在給定的起點跳進你的表格,然後開始向前推進,在你離開懸崖之前記錄最後的「好」值,然後返回最後的「好」值你脫落後。

下面是創建表...

CREATE TABLE YourABTable (a int NOT NULL, b int NOT NULL) 

INSERT INTO YourABTable (a, b) VALUES (1, 0) 
INSERT INTO YourABTable (a, b) VALUES (2, 1) 
INSERT INTO YourABTable (a, b) VALUES (3, 2) 
INSERT INTO YourABTable (a, b) VALUES (4, 3) 
INSERT INTO YourABTable (a, b) VALUES (5, 0) 
INSERT INTO YourABTable (a, b) VALUES (6, 5) 
INSERT INTO YourABTable (a, b) VALUES (7, 5) 
INSERT INTO YourABTable (a, b) VALUES (8, 7) 
INSERT INTO YourABTable (a, b) VALUES (9, 0) 

GO; 

這裏的實際功能。

CREATE FUNCTION GetMaxA(@InputA int) RETURNS int 
AS 
BEGIN 

    DECLARE SearchCursor CURSOR 
     LOCAL 
     FORWARD_ONLY 
     FAST_FORWARD 
     READ_ONLY 
    FOR 
     SELECT 
      a, 
      b 
     FROM 
      YourABTable 
     WHERE 
      a >= @InputA 
     ORDER BY 
      a ASC 

    DECLARE @CurrentA int 
    DECLARE @CurrentB int 

    DECLARE @ReturnA int 

    SET @CurrentA = -1 
    SET @CurrentB = -1 

    SET @ReturnA = @CurrentA 

    OPEN SearchCursor 

    FETCH NEXT FROM SearchCursor 
    INTO @CurrentA, @CurrentB 

    --if you want to see where you start 
    --PRINT '@CurrentA = ' + CONVERT(nvarchar(max), @CurrentA) 
    --PRINT '@CurrentB = ' + CONVERT(nvarchar(max), @CurrentB) 

    IF @CurrentB = 0 
     BEGIN 
      SET @CurrentB = 1 
      --cheat to get the WHILE loop running at least once if you bingo a row where B = 0 on your input 
     END 

    WHILE @@FETCH_STATUS = 0 AND @CurrentB > 0 
    BEGIN 
     SET @ReturnA = @CurrentA 

     FETCH NEXT FROM SearchCursor 
     INTO @CurrentA, @CurrentB 
    END 

    CLOSE SearchCursor ; 
    DEALLOCATE SearchCursor ; 

    RETURN @ReturnA 
END; 

值得注:LEAD()不是魔術,你可以在SQL的其他版本的效仿。你可以通過將表加入自己(一個自加入),加入一個鍵偏移量(即table1.key = table2.key + 1)來實現,但要做到這一點,你必須使用ROW_NUMBER作爲派生的臨時密鑰在你的記錄集中。這是因爲您不能保證沒有行被刪除,這會在您的列a序列中留下間隙,這會破壞這樣的連接。這將是一個非常有效的方法,但爲了簡單起見,我更喜歡上述方法。

+0

非常感謝喬,這正是我所需要的。 – gips