La respuesta es simple.
SQL Server no materializa CTE. Los alinea, como puede ver en los planes de ejecución.
Otros DBMS pueden implementarlo de manera diferente, un ejemplo bien conocido es Postgres, que materializa CTE (esencialmente crea tablas temporales para CTE detrás del capó).
Si la materialización explícita de resultados intermedios en tablas temporales explícitas es más rápida, depende de la consulta.
En consultas complejas, la sobrecarga de escribir y leer datos intermedios en tablas temporales se puede compensar con planes de ejecución más simples y eficientes que el optimizador puede generar.
Por otro lado, en Postgres, CTE es una "valla de optimización" y el motor no puede empujar predicados a través del límite de CTE.
A veces una manera es mejor, a veces otra. Una vez que la complejidad de la consulta crece más allá de cierto umbral, un optimizador no puede analizar todas las formas posibles de procesar los datos y tiene que decidirse por algo. Por ejemplo, el orden en el que unir las tablas. El número de permutaciones crece exponencialmente con el número de tablas para elegir. Optimiser tiene un tiempo limitado para generar un plan, por lo que puede hacer una mala elección cuando todos los CTE están alineados. Cuando divide manualmente una consulta compleja en otras más pequeñas y simples, necesita comprender lo que está haciendo, pero el optimizador tiene más posibilidades de generar un buen plan para cada consulta simple.