You can use the Numbers table to βcreateβ incremental steps. Here is my setup:
CREATE TABLE #floors ( [start_level] INT, [end_level] INT, [duration] DECIMAL(10, 4), [user] VARCHAR(50) ) INSERT INTO #floors ([start_level], [end_level], [duration], [user]) VALUES (1,1,10,'a'), (1,2,5,'a'), (2,5,27,'b'), (5,6,3,'c')
Then, using the Numbers table and some LEFT JOIN / COALESCE logic:
-- Create a Numbers table ;WITH Numbers_CTE AS (SELECT TOP 50 [Number] = ROW_NUMBER() OVER( ORDER BY (SELECT NULL)) FROM sys.columns) SELECT [start_level] = COALESCE(n.[Number], f.[start_level]), [end_level] = COALESCE(n.[Number] + 1, f.[end_level]), [duration] = CASE WHEN f.[end_level] = f.[start_level] THEN f.[duration] ELSE f.[duration] / ( f.[end_level] - f.[start_level] ) END, f.[user] FROM
Here are the logical steps:
- LEFT JOIN In the Numbers table for cases where end_level> = start_level + 2 (this gives us several rows - one for each ascending step)
- new start_level = If the LEFT JOIN "completes": take Number from the Numbers table, otherwise: take the original start_level
- new end_level = If LEFT JOIN "completes": take Number + 1, else: take the original end_level
- new duration = If end_level = start_level: take the initial duration (to avoid dividing by 0), otherwise: take the average duration over end_level - start_level
source share