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];