从sql表递归拉取值

时间:2012-02-06 19:30:04

标签: sql sql-server-2005 common-table-expression

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

这是更新记录时的模拟,新记录存储其旧记录的ID。该链条继续并下降到为该客户创建的第一个记录。

我想要的是发出像

这样的命令
  

从#customer中选择*,其中id = 3

这不仅应该包含id = 3的记录,而且还应该记录所有旧版本,即记录2和1。

  

从#customer id = 4

中选择*

应仅提取该记录(oldid = null)


增强功能(可选):如果有人发布了共享

  

从#customer中选择*,其中id = 8

我想以某种方式表明,该客户有一条新记录。我怎样才能做到这一点?假设我将在ASP.NET应用程序中使用。

2 个答案:

答案 0 :(得分:1)

这样的东西应该工作..(目前无法访问SQL Server会话进行测试..)

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

答案 1 :(得分:1)

可以使用CTE获取给定客户的所有旧记录。像

这样的东西
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

您可以选择指示是否存在较新的记录,您可能希望在结果集中包含较新的记录或仅包含一个标记,但无论如何查询都会像

一样
SELECT * FROM #Customer WHERE OldId = @CustomerId