Can you create nested WITH clauses for Common Table Expressions?

后端 未结 7 1170
花落未央
花落未央 2020-12-12 10:42
WITH y AS (
    WITH x AS (
        SELECT * FROM MyTable
    )
    SELECT * FROM x
)
SELECT * FROM y

Does something like this work? I tried it ear

相关标签:
7条回答
  • 2020-12-12 11:07

    These answers are pretty good, but as far as getting the items to order properly, you'd be better off looking at this article http://dataeducation.com/dr-output-or-how-i-learned-to-stop-worrying-and-love-the-merge

    Here's an example of his query.

    WITH paths AS ( 
        SELECT 
            EmployeeID, 
            CONVERT(VARCHAR(900), CONCAT('.', EmployeeID, '.')) AS FullPath 
        FROM EmployeeHierarchyWide 
        WHERE ManagerID IS NULL
    
        UNION ALL
    
        SELECT 
            ehw.EmployeeID, 
            CONVERT(VARCHAR(900), CONCAT(p.FullPath, ehw.EmployeeID, '.')) AS FullPath 
        FROM paths AS p 
            JOIN EmployeeHierarchyWide AS ehw ON ehw.ManagerID = p.EmployeeID 
    ) 
    SELECT * FROM paths order by FullPath
    
    0 讨论(0)
  • 2020-12-12 11:07

    we can create nested cte.please see the below cte in example

    ;with cte_data as 
    (
    Select * from [HumanResources].[Department]
    ),cte_data1 as
    (
    Select * from [HumanResources].[Department]
    )
    
    select * from cte_data,cte_data1
    
    0 讨论(0)
  • 2020-12-12 11:17

    While not strictly nested, you can use common table expressions to reuse previous queries in subsequent ones.

    To do this, the form of the statement you are looking for would be

    WITH x AS 
    (
        SELECT * FROM MyTable
    ), 
    y AS 
    (
        SELECT * FROM x
    )
    SELECT * FROM y
    
    0 讨论(0)
  • 2020-12-12 11:20

    Nested 'With' is not supported, but you can always use the second With as a subquery, for example:

    WITH A AS (
                    --WITH B AS ( SELECT COUNT(1) AS _CT FROM C ) SELECT CASE _CT WHEN 1 THEN 1 ELSE 0 END FROM B --doesn't work
                    SELECT CASE WHEN count = 1 THEN 1 ELSE 0 END AS CT FROM (SELECT COUNT(1) AS count FROM dual)
                    union all
                    select 100 AS CT from dual
               )
                  select CT FROM A
    
    0 讨论(0)
  • 2020-12-12 11:26

    With does not work embedded, but it does work consecutive

    ;WITH A AS(
    ...
    ),
    B AS(
    ...
    )
    SELECT *
    FROM A
    UNION ALL
    SELECT *
    FROM B
    

    EDIT Fixed the syntax...

    Also, have a look at the following example

    SQLFiddle DEMO

    0 讨论(0)
  • 2020-12-12 11:29

    I was trying to measure the time between events with the exception of what one entry that has multiple processes between the start and end. I needed this in the context of other single line processes.

    I used a select with an inner join as my select statement within the Nth cte. The second cte I needed to extract the start date on X and end date on Y and used 1 as an id value to left join to put them on a single line.

    Works for me, hope this helps.

    cte_extract
    as 
    (
        select ps.Process as ProcessEvent
            , ps.ProcessStartDate 
            , ps.ProcessEndDate 
            -- select strt.*
        from dbo.tbl_some_table ps 
        inner join (select max(ProcessStatusId) ProcessStatusId 
                        from dbo.tbl_some_table 
                    where Process = 'some_extract_tbl' 
                    and convert(varchar(10), ProcessStartDate, 112) < '29991231'
                    ) strt on strt.ProcessStatusId = ps.ProcessStatusID
    ), 
    cte_rls
    as 
    (
        select 'Sample' as ProcessEvent, 
         x.ProcessStartDate, y.ProcessEndDate  from (
        select 1 as Id, ps.Process as ProcessEvent
            , ps.ProcessStartDate 
            , ps.ProcessEndDate
            -- select strt.*
        from dbo.tbl_some_table ps 
        inner join (select max(ProcessStatusId) ProcessStatusId 
                        from dbo.tbl_some_table 
                    where Process = 'XX Prcss' 
                    and convert(varchar(10), ProcessStartDate, 112) < '29991231'
                    ) strt on strt.ProcessStatusId = ps.ProcessStatusID
        ) x
        left join (
            select 1 as Id, ps.Process as ProcessEvent
                , ps.ProcessStartDate 
                , ps.ProcessEndDate
                -- select strt.*
            from dbo.tbl_some_table ps 
            inner join (select max(ProcessStatusId) ProcessStatusId
                        from dbo.tbl_some_table 
                        where Process = 'YY Prcss Cmpltd' 
                        and convert(varchar(10), ProcessEndDate, 112) < '29991231'
                        ) enddt on enddt.ProcessStatusId = ps.ProcessStatusID
                ) y on y.Id = x.Id 
    ),
    

    .... other ctes

    0 讨论(0)
提交回复
热议问题