问题
I have two CTEs and I want to combine them together. I tried a lot but I got a syntax errors. First Part:
declare @TimeRanges as TABLE (SessionStart datetime, SessionEnd datetime);
with TimeRanges as (
select @Start as StartTime, @Start + @TimeRange as EndTime
union all
select StartTime + @TimeRange, EndTime + @TimeRange
from TimeRanges
where EndTime < @Finish )
Here is the second part:
;with cte as
(
select SessionStartTime as changetime,1 as CC from Calls
union all
select SessionCloseTime,-1 from Calls
)
select top 1 changetime,rt from
(
select * from cte
cross apply
(select SUM(cc) as rt from cte c where c.changetime<=cte.changetime) rt
) v
order by rt desc
What I want to do:
@Start datetime,
@Finish datetime,
@TimeRange time
AS
BEGIN
SET NOCOUNT ON;
declare @res int SET @res = 0
declare @TimeRanges as TABLE (SessionStart datetime, SessionEnd datetime);
with TimeRanges as
( select @Start as StartTime, @Start + @TimeRange as EndTime
union all
select StartTime + @TimeRange, EndTime + @TimeRange
from TimeRanges
where EndTime < @Finish ),
cte as
(
select SessionStart as changetime,1 as CC from TimeRanges
union all
select SessionEnd,-1 from TimeRanges
)
select top 1 changetime,rt from
(
select * from cte
cross apply
(select SUM(cc) as rt from cte c where c.changetime<=cte.changetime) rt
) v
order by rt desc
select StartTime, EndTime,cte.rt
from TimeRanges as TR left outer join
dbo.Test as Test on TR.StartTime <= Test.SessionStartTime
and Test.SessionCloseTime < TR.EndTime
where Test.ScenarioID = 24
group by TR.StartTime, TR.EndTime,cte.rt
END
First CTE, groups or splits times according to the @timerange between StartTime and EndTime. For Example, StartTime 11:00 EndTime 11:10 and TimeRange 05:00(5 min) then splits them into two parts: 11:00 - 11:05 and 11:05 - 11:10. Second CTE counts something for each these ranges. Not important in here. I tried to combine them but I get there errors:
Invalid column name 'SessionStart'
Invalid object name 'TimeRanges'
回答1:
Because in the TimeRanges
CTE, you've named the columns differently:
with TimeRanges as
( select @Start as StartTime, @Start + @TimeRange as EndTime --StartTime and EndTime
union all
select StartTime + @TimeRange, EndTime + @TimeRange
from TimeRanges
where EndTime < @Finish ),
cte as
(
select StartTime as changetime,1 as CC from TimeRanges --StartTime, not SessionStart
union all
select EndTime,-1 from TimeRanges --EndTime
)
select top 1 changetime,rt from
(
select * from cte
cross apply
(select SUM(cc) as rt from cte c where c.changetime<=cte.changetime) rt
) v
order by rt desc
But you then attempt to refer to the CTE again in your second query. You can't do that - each CTE applies to a single query.
You could repeat it:
with TimeRanges as
( select @Start as StartTime, @Start + @TimeRange as EndTime --StartTime and EndTime
union all
select StartTime + @TimeRange, EndTime + @TimeRange
from TimeRanges
where EndTime < @Finish )
select StartTime, EndTime,cte.rt
from TimeRanges as TR left outer join
dbo.Test as Test on TR.StartTime <= Test.SessionStartTime
and Test.SessionCloseTime < TR.EndTime
where Test.ScenarioID = 24
group by TR.StartTime, TR.EndTime,cte.rt
来源:https://stackoverflow.com/questions/13134320/combining-multiple-cte-in-tsql