如何缩短 SQL 脚本

How to shorten SQL script

根据我下面的代码,我使用 cursor 获取 WInstance table 中的所有信息。但是,由于 cursor,我的查询可能 performance 有问题。有什么方法可以使用嵌套-select 而不是 cursor?请分享您的想法。

我的任务是只得到 1 个相同的 ItemIDSequenceIDTaskStatusListIDWebIDSiteID.

从技术上讲,有很多相同的 ItemIDSequenceIDTaskStatusListIDWebIDSiteIDWInstanceWProgress 的 table 加入 AssignTask = 'Assign task'。因此,我使用 distinctcursor 循环以仅获得 order by.

的前 1 名

这是我的代码:

CREATE PROCEDURE dbo.CustomTasksHistory
    (
      @Username NVARCHAR(255)
    )
AS
    DECLARE @TempTableStatus TABLE
        (
          ItemID INT ,
          SequenceID INT ,
          TaskStatus NVARCHAR(25) ,
          ListID UNIQUEIDENTIFIER ,
          WebID UNIQUEIDENTIFIER ,
          SiteID UNIQUEIDENTIFIER
        );

    DECLARE @ItemID INT;
    DECLARE @SequenceID INT;
    DECLARE @ListID UNIQUEIDENTIFIER;
    DECLARE @WebID UNIQUEIDENTIFIER;
    DECLARE @SiteID UNIQUEIDENTIFIER;
    DECLARE @AssignTask VARCHAR(25);
    SET @AssignTask = 'Assign task';

    -- Select final TaskStatus of each ItemID with its SequenceID --
    DECLARE cursor_ItemID CURSOR FAST_FORWARD READ_ONLY FOR
        SELECT  DISTINCT
                WI.ItemID ,
                WP.SequenceID ,
                WI.ListID ,
                WI.WebID ,
                WI.SiteID
        FROM    dbo.WInstance WI
                INNER JOIN dbo.WProgress WP ON WI.InstanceID = WP.InstanceID
        WHERE   WP.CurrentActivityTitle = @AssignTask;

    OPEN cursor_ItemID;

    FETCH NEXT FROM cursor_ItemID INTO @ItemID, @SequenceID, @ListID, @WebID, @SiteID;

    WHILE @@FETCH_STATUS = 0
        BEGIN
            INSERT  INTO @TempTableStatus
                    ( ItemID ,
                      SequenceID ,
                      TaskStatus ,
                      ListID ,
                      WebID ,
                      SiteID
                    )
                    SELECT TOP 1
                            WI.ItemID ,
                            WP.SequenceID ,
                            CASE WHEN WP.ActivityComplete = 0
                                 THEN 'Not Started'
                                 ELSE 'Completed'
                            END AS 'TaskStatus' ,
                            WI.ListID ,
                            WI.WebID ,
                            WI.SiteID
                    FROM    dbo.WInstance WI
                            INNER JOIN dbo.WProgress WP ON WI.InstanceID = WP.InstanceID
                    WHERE   WP.CurrentActivityTitle = @AssignTask
                            AND WI.ItemID = @ItemID
                            AND WP.SequenceID = @SequenceID
                            AND WI.ListID = @ListID
                            AND WI.WebID = @WebID
                            AND WI.SiteID = @SiteID
                    ORDER BY TimeStamp DESC;

            FETCH NEXT FROM cursor_ItemID INTO @ItemID, @SequenceID, @ListID, @WebID, @SiteID;
        END;

    CLOSE cursor_ItemID;
    DEALLOCATE cursor_ItemID;

    SELECT  *
    FROM    @TempTableStatus;

您不需要使用游标。将其替换为以下查询

SELECT  ItemID, SequenceID, TaskStatus, ListID, WebID, SiteID
FROM
(
    SELECT  RN = ROW_NUMBER() OVER (PARTITION BY WP.CurrentActivityTitle,
                                                 WI.ItemID, WP.SequenceID, 
                                                 WI.ListID, WI.WebID, WI.SiteID 
                                    ORDER BY TimeStamp DESC),
            WI.ItemID ,
            WP.SequenceID ,
            CASE WHEN WP.ActivityComplete = 0
                 THEN 'Not Started'
                 ELSE 'Completed'
                 END AS 'TaskStatus' ,
            WI.ListID ,
            WI.WebID ,
            WI.SiteID
    FROM    dbo.WInstance WI
            INNER JOIN dbo.WProgress WP ON WI.InstanceID = WP.InstanceID
    WHERE   WP.CurrentActivityTitle = @AssignTask
) D
WHERE RN = 1;