展平递归数据

时间:2020-06-29 09:43:23

标签: tsql azure-sql-database

我有一个表格glclassifications(精确软件),看起来像这样:

CREATE TABLE [glclassifications](
    [ID] [nvarchar](500) NULL, --(contains uniqueidentifier)
    [Code] [nvarchar](500) NULL,
    [Description] [nvarchar](500) NULL,
    [Parent] [nvarchar](500) NULL --(contains uniqueidentifier)
)

它包含分层的分类(因此,“父级”列引用了另一条记录的ID。)

我需要将此表“展平”,以便拥有

Parent_ID, 
Parent_code, 
Parent_description, 
--child1 
Child1_ID, 
Child1_code, 
Child1_description, 
--child2
Child2_ID....

-直到包括child9

以此类推。

我的前任给我留下了这个查询,它违反了我们一致同意的许多设计原则。其中之一不使用(临时)表。我想简化此脚本,最好将输出作为视图而不是表。值得一提的是,即使表中的列数较少,结果视图也需要为8个子列传递列...

/* drop duplicates  in glclassifications */
WITH CTE AS (
    SELECT ROW_NUMBER() OVER (
        PARTITION BY ID
        ORDER BY ( SELECT 0)
    ) RN
    FROM   [dbo].[glclassifications]
)

DELETE FROM CTE
WHERE  RN > 1;
/* drop tmp table */
DROP TABLE IF EXISTS #H;
CREATE TABLE #H (    
    Code varchar(100),
    Description varchar(250),
    ID varchar(100),
    Division int
)
/* declare table */
DECLARE @n INT = 1
DECLARE @Sql varchar(50)
WHILE @n < 10 BEGIN
    DECLARE @col_name varchar(10) = CONCAT('Code_' , @n) 
    SET @Sql = 'ALTER TABLE #H ADD ' + QUOTENAME(@col_name) + ' varchar(20) NULL'
    EXEC (@Sql)
    SET @col_name = CONCAT('Name_' , @n) 
    SET @Sql = 'ALTER TABLE #H ADD ' + QUOTENAME(@col_name) + ' varchar(250) NULL'
    EXEC (@Sql)
    SET @n = @n + 1 
END
/* insert level 1 */
INSERT INTO #H (Code,[Description],ID,Division,Code_1, Name_1) 
SELECT 
Code,Description,ID,bip_office,Code,Description 
FROM 
[dbo].[glclassifications]
WHERE Parent = ''
/* insert level 2 */
INSERT INTO #H (Code,[Description],ID,Division,Code_1, Name_1, Code_2, Name_2) 
SELECT 
e.Code,e.Description,e.Id,e.bip_office,Code_1,Name_1,e.Code,e.Description
FROM 
[dbo].[glclassifications] e
JOIN #H h on h.ID = e.Parent 
WHERE e.ID not in (SELECT DISTINCT ID from #H ) AND Parent IS NOT NULL ;
/* insert level 3 */
INSERT INTO #H (Code,[Description],ID,Division,Code_1, Name_1, Code_2, Name_2,Code_3, Name_3) 
SELECT 
e.Code,e.Description,e.Id,e.bip_office, Code_1,Name_1,Code_2, Name_2,e.Code,e.Description
FROM 
[dbo].[glclassifications] e
JOIN #H h on h.ID = e.Parent 
WHERE e.ID not in (SELECT DISTINCT ID from #H ) AND Parent IS NOT NULL ;
/* insert level 4 */
INSERT INTO #H (Code,[Description],ID,Division,Code_1, Name_1, Code_2, Name_2,Code_3, Name_3, Code_4, Name_4) 
SELECT 
e.Code,e.Description,e.Id,e.bip_office, Code_1,Name_1,Code_2, Name_2,Code_3, Name_3,e.Code,e.Description
FROM 
[dbo].[glclassifications] e
JOIN #H h on h.ID = e.Parent 
WHERE e.ID not in (SELECT DISTINCT ID from #H ) AND Parent IS NOT NULL ;
/* insert level 5 */
INSERT INTO #H (Code,[Description],ID,Division,Code_1, Name_1, Code_2, Name_2,Code_3, Name_3, Code_4, Name_4, Code_5, Name_5) 
SELECT 
e.Code,e.Description,e.Id,e.bip_office,Code_1,Name_1,Code_2, Name_2,Code_3, Name_3,Code_4, Name_4,e.Code,e.Description
FROM 
[dbo].[glclassifications] e
JOIN #H h on h.ID = e.Parent 
WHERE e.ID not in (SELECT DISTINCT ID from #H ) AND Parent IS NOT NULL ;
/* insert level 6 */
INSERT INTO #H (Code,[Description],ID,Division,Code_1, Name_1, Code_2, Name_2,Code_3, Name_3, Code_4, Name_4, Code_5, Name_5,Code_6, Name_6) 
SELECT 
e.Code,e.Description,e.Id,e.bip_office,Code_1,Name_1,Code_2, Name_2,Code_3, Name_3,Code_4, Name_4,Code_5, Name_5,e.Code,e.Description
FROM 
[dbo].[glclassifications] e
JOIN #H h on h.ID = e.Parent 
WHERE e.ID not in (SELECT DISTINCT ID from #H ) AND Parent IS NOT NULL ;
/* insert level 7 */
INSERT INTO #H (Code,[Description],ID,Division,Code_1, Name_1, Code_2, Name_2,Code_3, Name_3, Code_4, Name_4, Code_5, Name_5,Code_6, Name_6,Code_7, Name_8) 
SELECT 
e.Code,e.Description,e.Id,e.bip_office,Code_1,Name_1,Code_2, Name_2,Code_3, Name_3,Code_4, Name_4,Code_5, Name_5,Code_6, Name_6,e.Code,e.Description
FROM 
[dbo].[glclassifications] e
JOIN #H h on h.ID = e.Parent 
WHERE e.ID not in (SELECT DISTINCT ID from #H ) AND Parent IS NOT NULL;
/* store to table */
DROP TABLE IF EXISTS [dbo].[gb-hierarchie];


SELECT hie.*
INTO [dbo].[gb-hierarchie]
FROM #H hie 

我做到了

    WITH cte_org AS (
        SELECT       
            ID, 
            Code,
            Description,
            Parent
            
        FROM       
            [dbo].[glclassifications]
        WHERE len(parent) = 0
        UNION ALL
        SELECT 
            e.ID, 
            e.Code,
            e.Description,
            e.parent
        FROM 
            [dbo].[glclassifications] e
            INNER JOIN cte_org o 
                ON o.ID = e.parent
    )
    SELECT * FROM cte_org;

但是如何继续?

1 个答案:

答案 0 :(得分:0)

感谢Bill Jetzer:简单地将表自身连接8次是获得这些结果的最简单方法