With a recursive CTE, which basically creates a materialized path from root elements to elements:
; WITH cte (id, title, parentID, path) AS ( SELECT id, title, parentID, CAST(RIGHT(REPLICATE('0',9) + CAST(id AS VARCHAR(10)) ,10) AS VARCHAR(MAX)) FROM category WHERE parentID = 0 UNION ALL SELECT a.id, a.title, a.parentID, CAST(b.path + RIGHT(REPLICATE('0',9) + CAST(a.id AS VARCHAR(10)) ,10) AS VARCHAR(MAX)) FROM category AS a JOIN cte AS b ON b.id = a.parentID ) SELECT id, title, parentID FROM cte ORDER BY path ;
Test SQL script
source share