查找分层表中最后一条记录的最有效方法

时间:2013-12-10 11:54:12

标签: sql sql-server hierarchy hierarchical-data

我有一个存储论坛帖子的SQL表。每条记录都有一个ParentID,它是另一条记录的ID。如果它为null,则表示它是主论坛帖子,因此没有父记录。每个帖子都可以有多个级别的孩子。我正在寻找一个有效地通过子记录重复发现的函数来找到最后创建的函数(每个记录都有一个'Created'字段)。

我确实有一个存储过程,列出了属于特定父级的记录,但它非常占用CPU,在列出主要论坛帖子并显示上次回复的日期时无法使用。

如果有帮助,这是表格的基本结构:

CREATE TABLE [dbo].[ForumThreads](
    [ForumThreadID] [numeric](18, 0) IDENTITY(1,1) NOT NULL,
    [ForumID] [numeric](18, 0) NULL,
    [ParentID] [numeric](18, 0) NULL,
    [PostSubject] [nvarchar](500) NULL,
    [PostBody] [nvarchar](max) NULL,
    [Created] [datetime] NULL,
    [CreatedBy] [numeric](18, 0) NULL
);

1 个答案:

答案 0 :(得分:1)

我仔细阅读了你的回答并删除了我的第一个答案,因为它错了。这是一个SQL FIDDLE,其解决方案包括设置和递归CTE查询,该查询使用“TopLevelForumID”字段对所有相关论坛进行分组。此查询应该是高效的,但根据您的表统计信息,您可以添加INDEX以提高响应速度。

SQL Fiddle

添加了标量值函数,可以这样调用:

-- How yo use this Scalar-valued function
--SELECT [ForumThreadID]
--      ,[ForumID]
--      ,[ParentID]
--      ,[PostSubject]
--      ,[PostBody]
--      ,[Created]
--      ,[CreatedBy]
--      ,[dbo].[fn_getLastThread]([ForumID]) AS [LastThread]
--  FROM [dbo].[ForumThreads]

CREATE FUNCTION [dbo].[fn_getLastThread]
(
    @ParentForumID INT
)
RETURNS INT
AS
BEGIN

    DECLARE @Ret INT;

    -- recursive CTE query
    WITH hierarchy AS (

            -- select the parent row
            SELECT  [ForumID],[ParentID],[Created]
            FROM    ForumThreads
            WHERE   [ForumID]=@ParentForumID

            UNION ALL               
            SELECT  A.[ForumID],A.[ParentID],A.[Created]
            FROM    ForumThreads A
            INNER JOIN hierarchy H ON H.[ForumID] = A.[ParentID]
    )
    SELECT      TOP 1 @Ret = [ForumID]
    FROM        hierarchy
    ORDER BY    [Created] DESC
    OPTION      (MAXRECURSION 50); -- specify recursion limit (default is 100 if not specified)

    RETURN @Ret;

END