[sql] 공통 테이블 표현식에 대해 중첩 된 WITH 절을 작성할 수 있습니까?

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

이런 식으로 작동합니까? 나는 그것을 일찍 시도했지만 그것을 작동시킬 수 없었다.



답변

엄격하게 중첩되지는 않지만 공통 테이블 표현식을 사용하여 후속 쿼리에서 이전 쿼리를 재사용 할 수 있습니다.

이를 위해 찾고자하는 진술서의 형태는 다음과 같습니다.

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


답변

재귀 쿼리라고하는 다음을 수행 할 수 있습니다.

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

이 기능이 필요하지 않을 수 있습니다. 쿼리를 더 잘 구성하기 위해 다음을 수행했습니다.

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


답변

포함은 작동하지 않지만 연속적으로 작동합니다

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

편집
구문을 수정했습니다 …

또한 다음 예제를 살펴보십시오

SQLFiddle 데모


답변

이 답변은 꽤 좋지만 항목을 올바르게 주문하는 한이 기사 http://dataeducation.com/dr-output-or-how-i-learned-to-stop을 보는 것이 좋습니다.
걱정과 합병

다음은 그의 쿼리 예입니다.

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


답변

시작과 끝 사이에 여러 프로세스가있는 항목 하나를 제외하고 이벤트 사이의 시간을 측정하려고했습니다. 다른 단일 회선 프로세스의 맥락에서 이것이 필요했습니다.

Nth cte 내에서 select 문으로 내부 조인이있는 select를 사용했습니다. 두 번째 cte는 X의 시작 날짜와 Y의 종료 날짜를 추출하고 1을 id 값으로 사용하여 왼쪽 조인을 한 줄에 넣었습니다.

나를 위해 일하고, 이것이 도움이되기를 바랍니다.

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

…. 다른 상자들


답변

중첩 된 ‘With’는 지원되지 않지만 항상 두 번째 With를 하위 쿼리로 사용할 수 있습니다. 예를 들면 다음과 같습니다.

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


답변

우리는 중첩 된 cte를 만들 수 있습니다. 예제에서 아래 cte를 참조하십시오

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

select * from cte_data,cte_data1