The below code is run on a routine rather than say login time but being new to using FETCH NEXT I can't help think maybe there is a trick here to merge at least one of the SET lines.
The end results should give me the total unique users, how many completed a module and how many passed.
Fields are indexed on the table at this time but all additional thoughts welcome.
USE [DB] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER PROCEDURE [dbo].[spModuleStatisticsUnique2] -- Add the parameters for the stored procedure here AS DECLARE @i INT = 0; DECLARE @i INT = 0; DECLARE @Started int; DECLARE @Completed int; DECLARE @Passed int; DECLARE @ModuleID int; DECLARE merge_cursor CURSOR FAST_FORWARD FOR SELECT [ModuleID] FROM dbo.[TblModules] --ORDER BY [ModuleID] OPEN merge_cursor FETCH NEXT FROM merge_cursor INTO @ModuleID WHILE @@FETCH_STATUS = 0 BEGIN SET @Started = (Select Count(ID) FROM [TblResults] WHERE [ModuleID] = @ModuleID) SET @Completed = (Select Count(ID) FROM [TblResults] WHERE [ModuleID] = @ModuleID and ModuleDatecomplete <> '') SET @Passed = (Select Count(ID) FROM [TblResults] WHERE [ModuleID] = @ModuleID and Pass = 'Yes') UPDATE [TblModules] SET [Started] = @Started ,[Completed] = @Completed ,[Passed] = @Passed ,[PassedPercent] = ((@Passed * 100.0) / @Started) WHERE [ModuleID] = @ModuleID FETCH NEXT FROM merge_cursor INTO @ModuleID END CLOSE merge_cursor DEALLOCATE merge_cursor