2017-03-03 16 views
0

我有一個表「項目」和一個表「任務」與我的SQL數據庫中的分層數據。因此,這些任務具有與「parent」列鏈接到其parentID的子任務。 Root-Task-Parent爲0. 還有一個「project_id」列,它將任務引用到Project-Table中的特定項目。我現在想要做的是複製一個完整的任務與所有子任務,並將其引用到一個新項目。複製分層SQL數據與更新值

所以SQL查詢將

INSERT INTO tasks (text, date, parent, projectid) 
SELECT text, date, parent, 89 
FROM tasks WHERE projectid = 23 

,其中23是老項目的ID和89是該數據添加到項目中。

但問題是它保留父值,所以我的根任務被正確複製,但子任務仍然引用舊的任務。我如何更新parentID以便整個任務和子任務都引用新的根任務?

我想在我的PHP-Web-Application中使用這個項目管理工具,這樣用戶就可以簡單地選擇一個「主模板」來將其結構複製到一個新項目中。

謝謝你的幫助!

編輯: @Strawberry:我用dhtmlxgantt來創建和更新任務,但我想用SQL查詢解決它。一個例子表是這樣的: Screenshot of Database

因此,在這種情況下,我想重複的「工程」,「項目2」用新的專案編號,並與parentIDs匹配的子任務

+0

你能提供一個例子,一個數據集的方式和期望的結果? – Strawberry

+0

這是你應該願意支付的那種問題:) – Anand

+0

你對付錢有什麼意義? – Nicoloss

回答

0

我認爲[文字]字段對於每個項目都是唯一的。

在這個假設下,這裏是我的查詢

--DROP TABLE [Tasks] 

-- Create table 
CREATE TABLE [dbo].[Tasks](
[Id] [bigint] IDENTITY(1,1) NOT NULL, 
[Text] [varchar](10) NOT NULL, -- Assume that [Text] field is unique for each project 
[Name] [varchar](50) NOT NULL, 
[ParentId] [bigint] NULL, 
[ProjectId] [bigint] NOT NULL, 
CONSTRAINT [PK_Tasks] PRIMARY KEY CLUSTERED 
(
[Id] ASC 
) 
) ON [PRIMARY] 

GO 

SET ANSI_PADDING OFF 
GO 

ALTER TABLE [dbo].[Tasks] WITH CHECK ADD CONSTRAINT [FK_Tasks_Tasks] FOREIGN KEY([ParentId]) 
REFERENCES [dbo].[Tasks] ([Id]) 
GO 

-- Remove all the data from the table and reseed the identity value 
DELETE FROM [Tasks] 
DBCC CHECKIDENT ('Tasks', RESEED, 1) 

-- Sample Data population starts here... 
INSERT INTO [Tasks] (text, Name, [ParentId], ProjectId) 
SELECT 'A', 'A', null, 101 union ALL 
SELECT 'B', 'B', null, 101 union ALL 
SELECT 'C', 'C', null, 101 

INSERT INTO [Tasks] (text, Name, [ParentId], ProjectId) 
SELECT 'A1', 'A 1', (SELECT [Id] FROM [Tasks] WHERE [Text] = 'A'), 101 union ALL 
SELECT 'A2', 'A 2', (SELECT [Id] FROM [Tasks] WHERE [Text] = 'A'), 101 union ALL 
SELECT 'A3', 'A 3', (SELECT [Id] FROM [Tasks] WHERE [Text] = 'A'), 101 union ALL 
SELECT 'A4', 'A 4', (SELECT [Id] FROM [Tasks] WHERE [Text] = 'A'), 101 union ALL 
SELECT 'B1', 'B 1', (SELECT [Id] FROM [Tasks] WHERE [Text] = 'B'), 101 union ALL 
SELECT 'B2', 'B 2', (SELECT [Id] FROM [Tasks] WHERE [Text] = 'B'), 101 union ALL 
SELECT 'B3', 'B 3', (SELECT [Id] FROM [Tasks] WHERE [Text] = 'B'), 101 union ALL 
SELECT 'C1', 'C 1', (SELECT [Id] FROM [Tasks] WHERE [Text] = 'C'), 101 union ALL 
SELECT 'C2', 'C 2', (SELECT [Id] FROM [Tasks] WHERE [Text] = 'C'), 101 union ALL 
SELECT 'C3', 'C 3', (SELECT [Id] FROM [Tasks] WHERE [Text] = 'C'), 101 

INSERT INTO [Tasks] (text, Name, [ParentId], ProjectId) 
SELECT 'A11', 'A 11', (SELECT [Id] FROM [Tasks] WHERE [Text] = 'A 1'), 101 union ALL 
SELECT 'A41', 'A 41', (SELECT [Id] FROM [Tasks] WHERE [Text] = 'A 4'), 101 

-- Sample Data population ends here... 
GO 
-- Copy all the data from project 101 and insert it as 102 with parent id as null 
INSERT INTO [Tasks] (text, Name, [ParentId], ProjectId) -- other column names can be here... 
SELECT text, Name, null, 102 -- Other column values can be here... 
FROM [Tasks] where ProjectId = 101 

-- Update the parent id using the text field 
UPDATE A 
    SET A.[ParentId] = C.NewParentId 
FROM [Tasks] A 
    INNER JOIN (SELECT Child.text, Parent.[Text] Parenttext 
       FROM [Tasks] Child 
        INNER JOIN [Tasks] Parent 
         ON Child.[ParentId] = Parent.[Id] 
       WHERE Child.ProjectId = 101 
       ) B 
     ON A.[Text] = B.[Text] 
     LEFT JOIN (
       SELECT [Id] NewParentId, [Text] 
       FROM [Tasks] 
       WHERE ProjectId = 102 
       ) C 
     ON B.Parenttext = C.text 
WHERE ProjectId = 102 


SELECT * FROM [Tasks] WHERE ProjectId = 102 Order By [Text] 

我希望這可以幫助你