You can also get the average per minute if someone wants you to say, tell them on average how long your ETL will collect X records.
SELECT AVG(ABC.TOTAL_MINUTE) FROM (Select DateAdd(minute, DateDiff(minute, 0,createdon),0) AS [DAY_MINUTE], Count(*) AS [TOTAL_MINUTE] From contactbase Group By DateAdd(minute, DateDiff(minute, 0, createdon), 0)) ABC here
Or, if you want more information, you can give interest to complete it all ... put it in proc ... you get this idea.
DECLARE @TtlToProcess AS DECIMAL --- put arbitrary number of 2.5 million in as this is aproximate, could be replaces with true source count if known. SET @TtlToProcess = 2500000 SELECT DATEDIFF(MINUTE,MIN(CB.CreatedOn),max(CB.CreatedOn)) AS [Minutes Run], ROUND(100*(CAST(COUNT(*) AS DECIMAL)/CAST(@TtlToProcess AS DECIMAL)),1) AS [%Complete], ROUND(100-(100*(CAST(COUNT(*) AS DECIMAL)/CAST(@TtlToProcess AS DECIMAL))),1) AS [% Left], COUNT(*) AS [Rows Processed], @TtlToProcess-COUNT(*) AS [Rows Left], (SELECT AVG(ABC.TOTAL_MINUTE) FROM (SELECT DATEADD(MINUTE, DATEDIFF(MINUTE, 0, CreatedOn), 0) AS [DAY_MINUTE], COUNT(*) AS [TOTAL_MINUTE] FROM ContactBase GROUP BY DATEADD(MINUTE, DATEDIFF(MINUTE, 0, CreatedOn), 0)) AS ABC) AS [Avg. Rows per Minute], ROUND(((@TtlToProcess-COUNT(*))/(SELECT AVG(ABC.TOTAL_MINUTE) FROM (SELECT DATEADD(MINUTE, DATEDIFF(MINUTE, 0, CreatedOn), 0) AS [DAY_MINUTE], COUNT(*) AS [TOTAL_MINUTE] FROM ContactBase GROUP BY DATEADD(MINUTE,DATEDIFF(MINUTE, 0, CreatedOn), 0)) ABC))/CAST(60 AS DECIMAL),2) AS [Est. Hours Left],DATEADD(hh,((@TtlToProcess-COUNT(*))/(SELECT AVG(ABC.TOTAL_MINUTE) FROM (SELECT DATEADD(MINUTE, DATEDIFF(MINUTE, 0, CreatedOn), 0) AS [DAY_MINUTE], COUNT(*) AS [TOTAL_MINUTE] FROM ContactBase GROUP BY DATEADD(MINUTE, DATEDIFF(MINUTE, 0, CreatedOn), 0)) AS ABC))/CAST(60 AS DECIMAL),GETDATE()) AS [Est. Complete Date_Time] FROM dbo.ContactBase AS CB