вытащить значения рекурсивно из таблицы SQL - PullRequest
0 голосов
/ 06 февраля 2012
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

Это симуляция, когда запись обновляется, новая запись хранит идентификатор своей старой записи.Цепочка продолжается и переходит к самой первой записи, созданной для этого клиента.

Я хочу, чтобы я выполнил команду типа

select * from #customer, где id = 3

Это должно поместить не только запись с id = 3, но и всю ее старую версию, то есть также записи 2 и 1.

select * from #customer id = 4

должен извлекать только эту запись (oldid = null)


Улучшение (необязательно): если кто-то издает комманд

, выберите * из#customer где id = 8

Я хотел бы указать, что для этого клиента существует новая запись.Как я могу это сделать?Предположим, я собираюсь использовать в приложении ASP.NET.

Ответы [ 2 ]

1 голос
/ 06 февраля 2012

Может получить все старые записи для данного Клиента, используя 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
1 голос
/ 06 февраля 2012

, что-то вроде этого должно работать .. (У меня нет доступа к сеансу SQLServer в данный момент для тестирования ..)

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
...