T-SQL hierarchy - get breadcrumbs using query

五迷三道 提交于 2021-01-28 08:52:36

问题


I have virtual folder structure saved in database and I want to get the breadcrumbs from the current folder to the root. The data can be unsorted (but better will be sorted) and I want the parent folders of the current folder only.

The table definition is:

DECLARE Folders TABLE (
    FOL_PK INT IDENTITY(1,1) NOT NULL,
    FOL_Name VARCHAR(200) NOT NULL,
    FOL_FOL_FK INT NULL -- Foreign key to parent
)

And this is my solution:

DECLARE @FOL_PK INT = 5 -- Current folder PK

DECLARE @breadcrumbs TABLE (
    FOL_PK INT NOT NULL,
    FOL_Name VARCHAR(200) NOT NULL,
    FOL_FOL_FK INT NULL
)

DECLARE @isRoot BIT = 0
       ,@currentFolderPK INT
       ,@parentFK INT

-- Get current and parent folder PK
SELECT
    @currentFolderPK = FOL_PK
FROM
    Folder
WHERE
    FOL_PK = @FOL_PK

-- Breadcrumb
WHILE (@isRoot = 0)
BEGIN
    -- Save to breadcrumb
    INSERT INTO @breadcrumbs
        SELECT
            FOL_PK,
            FOL_Name,
            FOL_FOL_FK
        FROM
            Folder
        WHERE
            FOL_PK = @currentFolderPK

    -- Set parent as current
    SET @currentFolderPK =
    (
        SELECT
            FOL_FOL_FK
        FROM
            Folder
        WHERE
            FOL_PK = @currentFolderPK
    )

    -- Set flag for loop
    SET @isRoot = CASE 
                     WHEN ISNULL(@currentFolderPK, 0) = 0 THEN 1 
                     ELSE 0 
                  END
END

-- Return breadcrumbs
SELECT
    FOL_PK AS PK,
    FOL_Name AS Name,
    FOL_FOL_FK AS ParentFK
FROM
    @breadcrumbs

The problem is I am not very comfortable with the loop. Is there any other sophisticated solution how to do this?


回答1:


Try this using a recursive Common Table Expression (CTE):

SQL Fiddle

MS SQL Server 2008 Schema Setup:

CREATE TABLE [Folders](
    [FOL_PK] [int] IDENTITY(1,1) NOT NULL,
    [FOL_Name] [varchar](200) NOT NULL,
    [FOL_FOL_FK] [int] NULL,
 CONSTRAINT [PK__Folders__FOL_PK] PRIMARY KEY CLUSTERED 
(
    [FOL_PK] ASC
))

ALTER TABLE [dbo].[Folders]  
  WITH CHECK ADD  CONSTRAINT [FK_Folders_Folders] FOREIGN KEY([FOL_FOL_FK])
REFERENCES [dbo].[Folders] ([FOL_PK])

ALTER TABLE [dbo].[Folders] CHECK CONSTRAINT [FK_Folders_Folders]



INSERT INTO Folders(FOL_Name, FOL_FOL_FK)
VALUES ('Level 1', NULL),
       ('Level 1.1', 1),
       ('Level 1.2', 1),
       ('Level 1.3', 1),
       ('Level 1.2.1', 3),
       ('Level 1.2.2', 3),
       ('Level 1.2.3', 3),
       ('Level 1.2.2.1', 6),
       ('Level 1.2.2.2', 6),
       ('Level 1.2.2.3', 6),
       ('Level 1.3.1', 4),
       ('Level 1.3.2', 4)

Query 1:

DECLARE @FolderId Int = 9

;WITH CTE
AS
(
    SELECT FOL_PK AS PK, FOL_NAME As Name, FOL_FOL_FK AS ParentFK
    FROM Folders
    WHERE FOL_PK = @FolderId
    UNION ALL
    SELECT F.FOL_PK AS PK, F.FOL_NAME AS Name, F.FOL_FOL_FK AS ParentFK
    FROM Folders F
    INNER JOIN CTE C
        ON C.ParentFK = F.FOL_PK

)
SELECT *
FROM CTE

Results:

| PK |          Name | ParentFK |
|----|---------------|----------|
|  9 | Level 1.2.2.2 |        6 |
|  6 |   Level 1.2.2 |        3 |
|  3 |     Level 1.2 |        1 |
|  1 |       Level 1 |   (null) |


来源:https://stackoverflow.com/questions/31471611/t-sql-hierarchy-get-breadcrumbs-using-query

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!