从sql表中递归地提取值

从sql表中递归地提取值,sql,sql-server-2005,common-table-expression,Sql,Sql Server 2005,Common Table Expression,这是一个模拟,当更新记录时,新记录存储其旧记录的id。这条链条继续下去,一直延伸到为该客户创建的第一条记录 我想要的是我发出一个命令 从id=3的客户中选择* 这不仅应该放置id=3的记录,还应该放置其所有旧版本,即记录2和1 从客户id=4中选择* 应该只提取记录oldid=null 增强可选:如果有人发布了一个公共 从id=8的客户中选择* 我想指出的是,这个客户有一个新的记录。我该怎么做?假设我要在ASP.NET应用程序中使用。这样的东西应该可以用。。目前无法访问要测试的SQLServer

这是一个模拟,当更新记录时,新记录存储其旧记录的id。这条链条继续下去,一直延伸到为该客户创建的第一条记录

我想要的是我发出一个命令

从id=3的客户中选择*

这不仅应该放置id=3的记录,还应该放置其所有旧版本,即记录2和1

从客户id=4中选择*

应该只提取记录oldid=null

增强可选:如果有人发布了一个公共

从id=8的客户中选择*


我想指出的是,这个客户有一个新的记录。我该怎么做?假设我要在ASP.NET应用程序中使用。

这样的东西应该可以用。。目前无法访问要测试的SQLServer会话

create table #customer (
id int not null primary key,
cust_name varchar(12),
oldid int null
)

insert into #customer values(1,'XYZ',null) 
insert into #customer values(2,'XYZ',1) 
insert into #customer values(3,'XYZ',2) 
insert into #customer values(4,'ABC',null) 
insert into #customer values(5,'ABC',4) 
insert into #customer values(6,'DEF',null) 
insert into #customer values(7,'DEF',6) 
insert into #customer values(8,'DEF',7) 
insert into #customer values(9,'DEF',8) 


select * from #customer
-- output

id          cust_name    oldid
----------- ------------ -----------
1           XYZ          NULL
2           XYZ          1
3           XYZ          2
4           ABC          NULL
5           ABC          4
6           DEF          NULL
7           DEF          6
8           DEF          7
9           DEF          8

可以使用获取特定客户的所有旧记录。差不多

WITH n(id, cust_name) AS 
   (SELECT id, cust_name 
    FROM customer
    WHERE id = @id
        UNION ALL
    SELECT nplus1.id, nplus1.cust_name 
    FROM emp as nplus1, n
    WHERE n.empid = nplus1.oldid)
SELECT * FROM n
您可以选择指示是否存在较新的记录,您可能希望在结果集中包含较新的记录,或者只包含一个位标志,但在任何情况下,查询都是这样的

DECLARE @CustomerId int
SET @CustomerId = 8

;
WITH Records (Id, Cust_name, OldId) AS (
    SELECT * FROM #Customer
    WHERE Id = @CustomerId
    UNION ALL
    SELECT C.* FROM Records R
        INNER JOIN #Customer C on C.Id = R.OldId)
SELECT * FROM Records

看一看,我自己试了几个小时。我知道您必须使用公共表表达式,但到目前为止还不能正确使用。我也有+1'd。你能给我一个提示吗,如果可能的话,如何在子查询中也包括后面的记录。在我的两个查询之间添加一个联合ALL,它将返回所有旧记录加上一个新记录(如果存在)。我已经使它工作了。在选择答案时,它以相反的方向拉取记录。我可能也会用它来做点什么。你能不能请客户解释一下nplus1,n其中n.id=nplus1.oldid。n指的是什么?nplus1指向我知道的客户表。我想我知道了,但这对我来说是新的。n表示整个查询,与n。。。我仍然想知道这个语法
SELECT * FROM #Customer WHERE OldId = @CustomerId