最后的ID按顺序排列

时间:2015-11-17 14:29:39

标签: sql database sql-server-2008 function

我有这些数据。

  • A列是行号
  • B列是父母(A)的参考。

有两组。

    列中的
  • 0表示新组,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

1 个答案:

答案 0 :(得分:0)

现在我明白了。订单很重要,您想要玩Cliffhangers。如果您使用的是SQL Server 2012或更高版本,那么这将是LEAD()函数的绝佳应用,但您标记为2008,所以...该死的。

所以,没有LEAD(),但我们仍然有选择权。这是一个在给定的起始点跳入你的桌面的功能,然后开始向前跑,跟踪最后一个好的&#34;在你从悬崖上掉下来之前的价值(遇到下一个零),然后返回最后一个好的&#34;你跌倒后的价值。

这是表创建......

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)来实现此目的,但要做到这一点,您必须使用{{1} }作为记录集中的派生临时密钥。这是因为您无法保证不会删除任何行,这会在您的列ROW_NUMBER序列中留下空白,从而导致此类连接中断。这将是一种非常有效的方法,但为了简单起见,我更喜欢上述方法。