SQL - 选择没有while循环的链接数据

时间:2013-09-19 13:21:25

标签: sql sql-server

我正在研究一个问题,到目前为止,我能想到的唯一解决方案是使用带有select语句的while循环,但我正在寻找替代方案。情况是使用的一个表不使用更新语句来保存记录,当更新记录时,插入带有信息的新记录并分配新的主键。我的任务是使用任何主键来提取以前键的历史记录,这将通过一个由三列(table_PK,updatedFrom_id和updatedTo_id)组成的新表来处理。

任何人都有任何想法如何避免使用while循环来选择彼此相关的所有id?可以出现在任一列中但是如果没有更新则不会出现更新,并且对于可以更新的次数没有限制,并且该语句应该能够检索更新的内容和如果已更新它已更新的内容。

提前感谢您的帮助!

更新信息:

UpdateLinking

列:

UpdateLinking_PK,
UpdatedFrom_id,
UpdatedTo_id

示例数据:

UpdateLinking_PK UpdatedFrom_id UpdatedTo_id
77              11             22
78              22             33
79              33             44
80              44             55
81              55             66

UpdateFrom和UpdateTo都是来自单独表的密钥,可以真正为该表中的列添加更新,但由于其大小并且不会使用太多,将保持更新单独列出。 我想输入UpdateFrom或UpdateTo id并返回updatedFrom和updatedTo。如果输入的Id参数已更新,我想检查它是否在updatedFrom列中并按照它进行操作,直到最后一个UpdatedTo id没有出现在updatedFrom列中,反之亦然。

输入上述任何id的结果集应返回UpdatedFrom_id中的所有内容以及UpdatedTo_id列中的所有内容。

如果添加了一行:

UpdateLinking_PK UpdatedFrom_id UpdatedTo_id
82                  88              111

如果传递的参数I是44

,则应排除此项

3 个答案:

答案 0 :(得分:1)

WITH    q (id) AS
        (
        SELECT  id
        FROM    mytable
        WHERE   id = @myid
        UNION ALL
        SELECT  updatedFrom_id
        FROM    q
        JOIN    history
        ON      updatedTo_id = id
        )
SELECT  *
FROM    q

答案 1 :(得分:0)

您是否考虑过使用递归CTE?

答案 2 :(得分:0)

SQL Server 2012中的以下查询可以满足您的需求:

select u.table_Pk,
       lag(UpdatedId) over (partition by u.table_Pk order by UpdatedId) as UpdatedFrom_Id,
       u.updatedId as UpdatedTo_Id
from updates u;

此版本假定按顺序插入UpdatedId列,因为您没有提及可用于定义“previous”的日期时间字段(或其他字段)。

在SQL Server 2012之前,lag()功能不可用。这是一个替代品:

select u.table_Pk,
       (select top 1 UpdatedId
        from updated u2
        where u2.table_Pk = u.table_Pk and u2.UpdatedId < u.UpdatedId
        order by u2.UpdatedId desc
       ) as UpdatedFrom_Id,
       u.updatedId as UpdatedTo_Id
from updates u;