OK, first let me say I got this issue from:
I was trying to assist to figure out the issue, but got stumped when trying to debug the code one step at a time. I know the issue is due to the nested CTEs (because during debug if you dump each step aka cteX into temp tables the correct results are achieved) but not knowing how they work "under the hood" I cannot explain it in a sensible fashion outside of "it dont work yo." I suspect that it has something to do with how the compiler is trying to evaluate them all at the same time during run time but without more context I cant say for sure.
My question is merely about trying to understand how they work under the hood and how it relates to this situation. Now that I'm involved, I just want to understand the issue so I can speak to it in the future and learn something fun in the mean time.
Whoever answers here can also cross post on SO and answer there as well.
Code Set up:
declare @t1 TABLE (ID varchar(max),Action varchar(max), DateTime datetime );INSERT INTO @t1Select *from(VALUES ('w2337','Open','2020-11-06 12:28:10.000'),('w2337','Hold','2021-06-14 14:50:59.000'),('w2337','Open','2021-06-14 14:51:26.000'),('w2337','Hold','2021-06-15 14:50:59.000'),('w2337','Open','2021-06-17 14:51:26.000'),('w2337','Open','2021-06-18 14:51:26.000')) t (ID, Action, DateTime);with cte1 as (select [ID],[Action],[DateTime],ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) as [RegIndex],DENSE_RANK () OVER (ORDER BY ID) as [Index by ID],ROW_NUMBER() OVER (PARTITION BY ID ORDER BY [DateTime]) as [Index by DateTimeID],CASE when [Action]='Hold' then ROW_NUMBER() OVER (PARTITION BY ID,Action ORDER BY DateTime) end as [TimesHeld]FROM @t1 ),cte2 as (select *, MAX([TimesHeld]) OVER (PARTITION BY ID ORDER BY RegIndex ROWS UNBOUNDED PRECEDING) as [FD] from cte1 ),cte3 as(select *, CASE when [Action]='Open' then ROW_NUMBER() OVER (PARTITION BY ID,Action ORDER BY DateTime) end as [TimesOpened]from cte2 where FD is not null)select a.*, '' as thing, b.DateTime -- b.* alternating between the direct column versus all is the issuefrom cte3 a LEFT OUTER JOIN cte3 bON a.ID=b.ID and a.TimesHeld=b.TimesOpened where a.TimesHeld is not null and b.TimesOpened is not null
Details:
When compiling the queries below, in the final LEFT OUTER JOIN, if you select b.* you get the correct results. However if you just select the one column (datetime for example) the results are not correct.
Correct:
Image may be NSFW.
Clik here to view.
Incorrect: