使用更新的值在同一个表中复制分层SQL数据

时间:2017-03-03 15:44:15

标签: php mysql hierarchical

我在SQL数据库中有一个表“ projects ”和一个表“ tasks ”,其中包含分层数据。因此,任务具有子标记,这些子标记与“parent”列链接到其parentID。 Root-Task-Parent为0。 还有一个“project_id”列,它将任务引用到项目表中的特定项目。我现在要做的是复制包含所有子任务的整个任务并将其引用到新项目中。

所以SQL-Query将是

$("#explanationTest")[0].innerHTML(explainText)

// OR

document.getElementById('explanationTest').innerHTML(explainText)

其中23是旧项目的id,89是添加数据的项目。

但问题是它保留了父值,因此我的根任务被正确复制,但子任务仍然引用旧任务。我如何更新parentID,以便整个任务和子任务引用新的Root任务?

我想在我的PHP-Web-Application中使用这个项目管理工具,这样用户只需选择一个“主模板”将其结构复制到一个新项目。

感谢您的帮助!

编辑: @Strawberry:我使用dhtmlxgantt来创建和更新任务,但我想用SQL查询来解决它。示例表如下所示: Screenshot of Database

所以在这种情况下,我想将“Project”复制到“Project 2”,使用新的projectID并将子任务与parentID匹配

1 个答案:

答案 0 :(得分:0)

我认为[text]字段对于每个项目都是唯一的。

有了这个假设,这是我的查询

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

我希望这可以帮到你