在 SQL 服务器中使用数据透视和递归代码改进查询

Improve a query with Pivot and Recursive code in SQL Server

考虑到这两个 table,我需要达到下一个结果。

一个地区接受不同部门的服务。每个部门都属于三个(或更少)级别的层次结构。这个想法是在一列中表示该区域与其可能存在的所有层次结构之间的关系。对于没有父亲的记录,Level Nro 应该为 1。

到目前为止,我有这段代码 https://rextester.com/KYHKR17801 。我得到了我需要的结果。但是,性能不是最好的,因为 table 太大了,我不得不做很多转换:

如果有人可以提供任何建议来改进此查询的运行时间,我不会。

这似乎在一条语句中完成了您需要的一切:

WITH R AS
(
    SELECT 
        SA.AreaID, 
        S.[service], 
        S.[description], 
        L.[Level], 
        L.child_service,
        Recursion = 1
    FROM dbo.service_area AS SA
    JOIN dbo.[service] AS S
        ON S.[service] = SA.[Service]
    OUTER APPLY
    (
        -- Unpivot
        VALUES
            (1, S.level1),
            (2, S.level2),
            (3, S.level3)
    ) AS L ([Level], child_service)
    WHERE
        L.child_service IS NOT NULL

    UNION ALL

    SELECT 
        R.AreaID, 
        S.[service], 
        S.[description], 
        R.[Level], 
        child_service = CHOOSE(R.[Level], S.level1, S.level2, S.level3),
        Recursion = R.Recursion + 1
    FROM R
    JOIN dbo.[service] AS S
        ON S.[service] = R.child_service
)
SELECT
    R.AreaID, 
    R.[service],
    R.[description], 
    [Level] = 'Level' + CONVERT(char(1), R.[Level]), 
    [Level Nro] = ROW_NUMBER() OVER (
        PARTITION BY R.AreaID, R.[Level] 
        ORDER BY R.Recursion DESC)
FROM R
ORDER BY 
    R.AreaID ASC,
    R.[Level] ASC, 
    [Level Nro]
OPTION (MAXRECURSION 3);

以下索引将帮助递归部分快速定位行:

CREATE UNIQUE CLUSTERED INDEX cuq ON dbo.[service] ([service]);

db<>fiddle demo

如果你的SQL服务器版本没有CHOOSE,手写CASE语句:

CASE R.[Level] WHEN 1 THEN S.level1 WHEN 2 THEN S.level2 ELSE S.level3 END