如何缩短 SQL 脚本
How to shorten SQL script
根据我下面的代码,我使用 cursor
获取 WInstance
table 中的所有信息。但是,由于 cursor
,我的查询可能 performance 有问题。有什么方法可以使用嵌套-select 而不是 cursor
?请分享您的想法。
我的任务是只得到 1 个相同的 ItemID
、SequenceID
、TaskStatus
、ListID
、WebID
、SiteID
.
从技术上讲,有很多相同的 ItemID
、SequenceID
、TaskStatus
、ListID
、WebID
、SiteID
将 WInstance
和 WProgress
的 table 加入 AssignTask = 'Assign task'
。因此,我使用 distinct
和 cursor
循环以仅获得 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;
根据我下面的代码,我使用 cursor
获取 WInstance
table 中的所有信息。但是,由于 cursor
,我的查询可能 performance 有问题。有什么方法可以使用嵌套-select 而不是 cursor
?请分享您的想法。
我的任务是只得到 1 个相同的 ItemID
、SequenceID
、TaskStatus
、ListID
、WebID
、SiteID
.
从技术上讲,有很多相同的 ItemID
、SequenceID
、TaskStatus
、ListID
、WebID
、SiteID
将 WInstance
和 WProgress
的 table 加入 AssignTask = 'Assign task'
。因此,我使用 distinct
和 cursor
循环以仅获得 order by
.
这是我的代码:
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;