Pregunta

WITH y AS (
    WITH x AS (
        SELECT * FROM MyTable
    )
    SELECT * FROM x
)
SELECT * FROM y

¿Funciona algo como esto? Lo intenté antes pero no pude hacerlo funcionar.

¿Fue útil?

Solución

Si bien no está estrictamente anidado, puede usar expresiones de tabla comunes para reutilizar consultas anteriores en las posteriores.

Para hacer esto, la forma de la declaración que está buscando sería

WITH x AS 
(
    SELECT * FROM MyTable
), 
y AS 
(
    SELECT * FROM x
)
SELECT * FROM y

Otros consejos

Puede hacer lo siguiente, que se conoce como consulta recursiva:

WITH y
AS
(
  SELECT x, y, z
  FROM MyTable
  WHERE [base_condition]

  UNION ALL

  SELECT x, y, z
  FROM MyTable M
  INNER JOIN y ON M.[some_other_condition] = y.[some_other_condition]
)
SELECT *
FROM y

Es posible que no necesite esta funcionalidad. He hecho lo siguiente solo para organizar mejor mis consultas:

WITH y 
AS
(
  SELECT * 
  FROM MyTable
  WHERE [base_condition]
),
x
AS
(
  SELECT * 
  FROM y
  WHERE [something_else]
)
SELECT * 
FROM x

Con no funciona incrustado, pero funciona consecutivamente

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

EDIT Se corrigió la sintaxis ...

Además, eche un vistazo al siguiente ejemplo

SQLFiddle DEMO

Estas respuestas son bastante buenas, pero en lo que respecta a hacer que los artículos se ordenen correctamente, sería mejor mirar este artículo http: // dataeducation.com/dr-output-or-how-i-learned-to-stop-worrying-and-love-the-merge

Aquí hay un ejemplo de su consulta.

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

podemos crear cte anidado. Por ejemplo, vea el cte a continuación

;with cte_data as 
(
Select * from [HumanResources].[Department]
),cte_data1 as
(
Select * from [HumanResources].[Department]
)

select * from cte_data,cte_data1

Estaba tratando de medir el tiempo entre eventos con la excepción de qué entrada tiene múltiples procesos entre el inicio y el final. Necesitaba esto en el contexto de otros procesos de una sola línea.

Utilicé un select con una combinación interna como mi declaración select dentro del Nth cte. El segundo cte necesitaba extraer la fecha de inicio en X y la fecha de finalización en Y y usé 1 como valor de identificación para unir a la izquierda y ponerlos en una sola línea.

Funciona para mí, espero que esto ayude.

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 
),

.... otros ctes

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top