2015-11-17 94 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