I had an issue today with CTEs running on SQL Server 2016, at the moment I worked around it using table variables, however I am not sure if the behavior is wrong or I am reading the documentation wrong.
When you run this query:
with cte(id) as
(
select NEWID() as id
)
select * from cte
union all
select * from cte
I would expect two times the same guid, however there are 2 different ones. According to the documentation (https://docs.microsoft.com/en-us/sql/t-sql/queries/with-common-table-expression-transact-sql?view=sql-server-ver15) it "Specifies a temporary named result set". However, the above example shows, that it is not a result set, but executed whenever used.
This thread is not about finding a different approach, but much rather checking if there is something wrong with it.