USE [Database] IF OBJECT_ID('[Procedures].[tree_positions]', 'P') IS NOT NULL DROP PROCEDURE [Procedures].[tree_positions]; GO CREATE PROCEDURE [Procedures].[tree_positions] @product_type_id INT AS IF OBJECT_ID('[tempdb].[dbo].[#product_types_row_number]') IS NOT NULL DROP TABLE [dbo].[#product_types_row_number]; CREATE TABLE [#product_types_row_number] ( [id] INT NOT NULL, [parent_id] INT, [row_number] INT NOT NULL ); INSERT INTO [#product_types_row_number] SELECT [id], [parent_id], ROW_NUMBER() OVER (PARTITION BY [parent_id] ORDER BY [parent_id], [id] ASC) - 1 FROM [Tables].[product_types]; WITH [result] AS ( SELECT [id], [parent_id], [row_number] FROM [#product_types_row_number] WHERE [id] = @product_type_id UNION ALL SELECT [PT].[id], [PT].[parent_id], [PT].[row_number] FROM [result] AS [R] JOIN [#product_types_row_number] AS [PT] ON [PT].[id] = [R].[parent_id] ) SELECT [id], [parent_id], [row_number] FROM [result] ORDER BY [id];