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
Working out statistics for unique users
sql;sql server;stored procedure