2010-04-20 9 views
3

J'ai une table de serveur SQL:SQL récursif Calculée Date de

CREATE TABLE [Workflow].[MilestoneDate](
[MilestoneDateId] [int] IDENTITY(1,1) NOT NULL, 
[SpecifiedDate] [datetime] NULL, 
[RelativeDays] [int] NULL, 
[RelativeMilestoneDateId] [int] NULL, 
CONSTRAINT [PK_MilestoneDate] PRIMARY KEY CLUSTERED 
(
[MilestoneDateId] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 
ALTER TABLE [Workflow].[MilestoneDate] WITH CHECK ADD CONSTRAINT [FK_MilestoneDate_MilestoneDate] FOREIGN KEY([RelativeMilestoneDateId]) 
REFERENCES [Workflow].[MilestoneDate] ([MilestoneDateId]) 
GO 
ALTER TABLE [Workflow].[MilestoneDate] CHECK CONSTRAINT [FK_MilestoneDate_MilestoneDate] 

et il a des données qui pourraient ressembler à:

Id  Date       RelDays RelId 
49  2010-03-04 00:00:00.000  NULL NULL 
746 NULL       6  46 
747 NULL       20  746 
46  2010-02-18 00:00:00.000  NULL NULL 
48  2010-04-04 00:00:00.000  NULL NULL 
47  2010-05-04 00:00:00.000  NULL NULL 
748 NULL       14  48 

Ce que je dois pouvoir le faire est d'obtenir la valeur calculée date pour chaque ligne qui est soit la date s'il y en a un, soit la date de l'élément "parent" (en utilisant le RelId) plus les RelDays (qui peuvent être récursifs). Par exemple, la date calculée pour l'ID 747 est de 20 jours + 6 jours + 2010-02-18 et donc 2010-03-16.

+1

Chaque fois qu'il ya quelque chose qui doit être résolu de façon récursive dans SQL, vous devez utiliser une procédure stockée ou une fonctionnalité de requête récursive. SQL Server a quelque chose appelé Common Table Expressions qui peut vous aider. –

Répondre

3

essayez ceci (utilise un CTE qui est disponible uniquement sur SQL Server 2005 et plus):

DECLARE @YourTable table (Id int, Date datetime, RelDays int, RelId int) 
INSERT @YourTable VALUES (49 ,'2010-03-04 00:00:00.000',NULL ,NULL) 
INSERT @YourTable VALUES (746, NULL     ,6 ,46) 
INSERT @YourTable VALUES (747, NULL     ,20 ,746) 
INSERT @YourTable VALUES (46 ,'2010-02-18 00:00:00.000',NULL ,NULL) 
INSERT @YourTable VALUES (48 ,'2010-04-04 00:00:00.000',NULL ,NULL) 
INSERT @YourTable VALUES (47 ,'2010-05-04 00:00:00.000',NULL ,NULL) 
INSERT @YourTable VALUES (748, NULL     ,14 ,48) 

;WITH R AS 
(
    SELECT id,Date,RelDays,RelId --get all parents 
    FROM @YourTable 
    WHERE RelId IS NULL 
    UNION ALL --recursive go through all children, adding the days on 
    SELECT 
     y.id,r.Date+y.RelDays,y.RelDays,y.RelId 
     FROM @YourTable y 
      INNER JOIN R ON y.RelId=r.Id 
) 
select * from R 

SORTIE:

id   Date     RelDays  RelId 
----------- ----------------------- ----------- ----------- 
49   2010-03-04 00:00:00.000 NULL  NULL 
46   2010-02-18 00:00:00.000 NULL  NULL 
48   2010-04-04 00:00:00.000 NULL  NULL 
47   2010-05-04 00:00:00.000 NULL  NULL 
748   2010-04-18 00:00:00.000 14   48 
746   2010-02-24 00:00:00.000 6   46 
747   2010-03-16 00:00:00.000 20   746 

(7 row(s) affected) 
+0

Merci pour cela. Exactement ce dont j'ai besoin et fonctionne un régal. –