Search code examples
t-sqlvariablesviewcommon-table-expressiondeclare

T-SQL Use CTE to initialize variables inside a view


I need to create a view - it is composed by five UNION ALL statements. The difference between each statement is that the data is filter by different period:

For example:

SELECT  RecordName
       ,CASE
        WHEN RecordDate > DATEADD(WEEK,-1,GETUTCDATE()) THEN 'This week'
        END
UNION ALL
SELECT  RecordName
       ,CASE
        WHEN RecordDate > DATEADD(WEEK,-2,GETUTCDATE()) THEN 'Previos week'
        END
SELECT  RecordName
       ,CASE
        WHEN RecordDate > DATEADD(Year,-1,GETUTCDATE()) THEN 'Year ago'
        END

Then I am creating a pivot using the view.

Anyway, the "date" condition is calculate in more complex way. I am using GETUTCDATE() function too and this will return different value any millisecond.

That's why I want to use a CTE expression in order to initialize all date condition variables or to do the calculations one time only in the CTE, and then to use this date conditions in the SELECT-UNION clause.

The problem is, I am not able to join the information from the CTE with the SELECT statement below and when I try to use the date conditions directly (without join) it is not working ("Error - Invalid Column name").

This is a example of what I am trying to do:

WITH DatePeriods(ThisWeek,LastWeek,MonthToDate,QuarterToDate,YearToDate) AS
(
    SELECT  DATEADD(WEEK,-1,GETUTCDATE())  AS ThisWeek
           ,...                            AS LastWeek
           ,...                            AS MonthToDate
           ,...                            AS QuarterToDate
           ,DATEADD(YEAR,-1,GETUTCDATE())  AS YearToDate
)

SELECT  RecordName
       ,CASE
        WHEN RecordDate > ThisWeek THEN 'This week'
        END
UNION ALL
SELECT  RecordName
       ,CASE
        WHEN RecordDate > LastWeek THEN 'Previos week'
        END
SELECT  RecordName
       ,CASE
        WHEN RecordDate >YearToDate THEN 'Year ago'
        END

Solution

  • You have to use the CTE in the from clause of each query. You can do it with a cross apply.

    WITH DatePeriods(ThisWeek,LastWeek,MonthToDate,QuarterToDate,YearToDate) AS
    (
        SELECT  DATEADD(WEEK,-1,GETUTCDATE())  AS ThisWeek
               ,...                            AS LastWeek
               ,...                            AS MonthToDate
               ,...                            AS QuarterToDate
               ,DATEADD(YEAR,-1,GETUTCDATE())  AS YearToDate
    )
    
    SELECT  RecordName
           ,CASE
            WHEN RecordDate > ThisWeek THEN 'This week'
            END
    FROM YourTable 
      CROSS APPLY DatePeriods 
    UNION ALL
    SELECT  RecordName
           ,CASE
            WHEN RecordDate > LastWeek THEN 'Previos week'
            END
    FROM YourTable 
      CROSS APPLY DatePeriods 
    SELECT  RecordName
           ,CASE
            WHEN RecordDate >YearToDate THEN 'Year ago'
            END
    FROM YourTable 
      CROSS APPLY DatePeriods