【问题标题】:Find last record in a single-table chain (SQL Server)查找单表链中的最后一条记录 (SQL Server)
【发布时间】:2010-09-14 14:04:46
【问题描述】:

在SQL Server 2005中得到了这张表,用于维护合并操作的历史记录:

  • 列 FROM_ID (int)
  • 列 TO_ID (int)

现在我需要一个以原始 FROM_ID 作为输入的查询,并返回最后一个可用的 TO_ID。

例如:

  • ID 1 合并到 ID 2
  • 后来,ID 2 合并到 ID 3
  • 稍后,ID 3 再次合并到 ID 4

因此,我尝试组合的查询将作为输入(在我假定的 WHERE 子句中)ID 1,结果应该给我最后一个可用的 TO_ID,在本例中为 4。

我想我需要一些递归逻辑,但不知道如何开始。

谢谢!

马修

【问题讨论】:

    标签: sql sql-server-2005 chaining


    【解决方案1】:

    使用CTE 会起作用。

    测试脚本

    DECLARE @IDs TABLE (
      FromID INTEGER
      , ToID INTEGER
    )
    
    INSERT INTO @IDs
    SELECT           1, 2 
    UNION ALL SELECT 2, 3
    UNION ALL SELECT 3, 4
    

    SQL 语句

    ;WITH q AS (
        SELECT  FromID, ToID
        FROM    @IDs
        UNION ALL 
        SELECT  q.FromID, u.ToID
        FROM    q
                INNER JOIN @IDs u ON u.FromID = q.ToID
    )
    SELECT  FromID, MAX(ToID)
    FROM    q
    WHERE   FromID = 1
    GROUP BY
            FromID           
    

    【讨论】:

    • 对其进行了测试,几乎就在那里,除了 MAX(ToID) 不起作用,因为要合并到的目标 ID 不一定大于同一链中的先前目标 ID...所以 ID 1 可以合并到 3,然后 3 可以合并到 2,例如
    • 可以通过在合并信息中添加时间戳并选择“按日期顺序排列的前 1 个顺序”方法来修复它。但想知道是否可以在没有时间戳的情况下完成
    【解决方案2】:

    如果这对您有用,请给 Lieven 接受的答案,因为它基于他的代码。

    ;WITH q AS (
        SELECT  1 AS LEVEL, FromID, ToID
        FROM    @IDs
        WHERE FromID=1
        UNION ALL 
        SELECT  LEVEL + 1, q.FromID, u.ToID
        FROM    q
                INNER JOIN @IDs u ON u.FromID = q.ToID
    )
    
    SELECT TOP 1 ToID
     FROM q
    ORDER BY LEVEL DESC
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-17
      • 2013-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多