2011-12-06 2 views
11

공통 테이블 식에 대해 JOIN 하위 쿼리를 수행 할 수 있습니까? 그렇지 않다면 누군가 내가 아래에서하려고하는 것을 수행하는 방법을 알려줄 수 있습니까? 좋은 예가 될 것입니다. 예를 들어공통 테이블 식 (CTE)에 대한 T-SQL 조인

:

LEFT JOIN (

      ;WITH [UserDefined] 
       AS (SELECT *, -- Make sure we get only the latest revision. 
         ROW_NUMBER() OVER (PARTITION BY [ID] 
               ORDER BY [RevisionNumber] DESC) AS RN 
        FROM [syn_Change]) 

      SELECT [UserDefined].[ID] 
       ,[UserDefined].[ChangeNumber] 
       ,[UserDefined].[Usr_CoResponsibility] 
       ,[UserDefined].[Usr_StarFlowStatus] 

      FROM [UserDefined] 
      WHERE (RN = 1) 

      ) [UserColumns] 
ON [UserColumns].[ChangeNumber] = [CTE].[ChangeNumber] 

여기 내 전체 쿼리는 다음과 같습니다

;WITH CTE 
    AS (SELECT *, -- Make sure we get only the latest revision. 
      ROW_NUMBER() OVER (PARTITION BY [ItemID] 
            ORDER BY [RevisionNumber] DESC) AS RN 
     FROM [dw_Change]) 

SELECT [CTE].[ItemID] 
     ,[CTE].[ViewID] 
     ,[CTE].[FolderItemID] 
     ,[CTE].[RevisionNumber] 
     ,[CTE].[ChangeNumber] 
     ,[CTE].[Synopsis] 
     ,[CTE].[Description] 
     ,[CTE].[EnteredOn] 
     ,[CTE].[Responsibility] 
     --,[UserColumns].[Usr_CoResponsibility] 
     --,[UserColumns].[Usr_StarFlowStatus] 
     ,[CTE].[Status] -- This will display the human name on the front-end with code. 
     ,[Users].[F7] AS [ResponsibilityName] 
     ,[GroupName].[Name] AS [AppGroupName] 
     ,[AppName].[Name] AS [AppName] 
FROM CTE 
LEFT JOIN [S3] [Users] ON [Users].[F0] = [CTE].[Responsibility] 
LEFT JOIN (SELECT [Name], [ViewID] 
      FROM [dw_Folder] 
      WHERE ([FolderItemID] = -1)) [GroupName] 
ON [GroupName].[ViewID] = [CTE].[ViewID] 

LEFT JOIN (SELECT [Name], [ItemID] 
      FROM [dw_Folder] 
      WHERE ([FolderItemID] <> -1)) [AppName] 
ON [AppName].[ItemID] = [CTE].[FolderItemID] 

LEFT JOIN (

      ;WITH [UserDefined] 
       AS (SELECT *, -- Make sure we get only the latest revision. 
         ROW_NUMBER() OVER (PARTITION BY [ID] 
               ORDER BY [RevisionNumber] DESC) AS RN 
        FROM [syn_Change]) 

      SELECT [UserDefined].[ID] 
       ,[UserDefined].[ChangeNumber] 
       ,[UserDefined].[Usr_CoResponsibility] 
       ,[UserDefined].[Usr_StarFlowStatus] 

      FROM [UserDefined] 
      WHERE (RN = 1) 

      ) [UserColumns] 
ON [UserColumns].[ChangeNumber] = [CTE].[ChangeNumber] 

WHERE (RN = 1) 

정말 고마워요!

답변

30

CTE를 정의 할 때 나머지 쿼리가 수행되기 전에 CTE를 정의합니다. 그래서 당신은 쓸 수 없습니다 : 옆 빠른으로

LEFT JOIN (
    ;WITH CTE 
    ... 
) 

명이 WITH 앞에 ;을 넣어 이유는 이전의 모든 문이 종료 될 필요가 있기 때문입니다. 개발자는 다음이 필요하지 않을 것입니다 ; 모든 SQL 문을 종료하는 습관을 얻을 수있는,하지만 난

당신과 같이 여러 개의 CTE를 쓸 수 ... 빗나가 경우

WITH SomeCTE AS (
    SELECT ... 
    FROM ... 
), AnotherCTE AS (
    SELECT ... 
    FROM ... 
) 
SELECT * 
FROM SomeCTE LEFT JOIN 
    AnotherCTE ON ... 
; 
+6

그리고 하나의 CTE가 다른 CTE보다 먼저 정의되는 한, 그 CTE는 다음 CTE 내에서 참조 될 수 있습니다. – Bora

1

여러 CTE가있을 수 있습니다. 당신은 단지 그것들을 모두 상단에 놓아야 만합니다.

here를 참조하십시오 : 당신은, 그러나, 쉼표로 각 CTE를 분리하여 키워드로 한 후 여러 개의 CTE를 정의 할 수 있습니다

. 여러 CTE의가있는 경우

2

, 그들은 당신의 문장의 시작 부분에 있어야합니다 (쉼표로 구분 된-, 단 하나의 ;WITH는 CTE의 목록 시작) : 다음을 수행 할 수 있습니다

;WITH CTE AS (......), 
[UserDefined] AS (.......) 
SELECT..... 

SELECT 문에 두 가지 (또는 둘 이상)를 모두 사용하십시오.

3

먼저 여러 CTE를 선언해야합니다. 예 :

WITH CTE_1 AS 
(
    .... 
), 
CTE_2 AS 
(
    ... 
) 

SELECT  * 
FROM   FOO 
LEFT JOIN  CTE_1 
LEFT JOIN  CTE_2 
1
; 
WITH 
    RANKED_CTE AS 
(
    SELECT 
    *, 
    ROW_NUMBER() OVER (PARTITION BY [ItemID] ORDER BY [RevisionNumber] DESC) AS RN 
    FROM 
    [dw_Change] 
) 
, 
    CTE AS 
(
    SELECT 
    * 
    FROM 
    RANKED_CTE 
    WHERE 
    RN = 1 
) 
, 
    GroupName AS 
(
    SELECT 
    [Name], [ViewID] 
    FROM 
    [dw_Folder] 
    WHERE 
    ([FolderItemID] = -1) 
) 
, 
    AppName AS 
(
    SELECT 
    [Name], [ItemID] 
    FROM 
    [dw_Folder] 
    WHERE 
    ([FolderItemID] <> -1) 
) 
SELECT [CTE].[ItemID] 
     ,[CTE].[ViewID] 
     ,[CTE].[FolderItemID] 
     ,[CTE].[RevisionNumber] 
     ,[CTE].[ChangeNumber] 
     ,[CTE].[Synopsis] 
     ,[CTE].[Description] 
     ,[CTE].[EnteredOn] 
     ,[CTE].[Responsibility] 
     --,[UserColumns].[Usr_CoResponsibility] 
     --,[UserColumns].[Usr_StarFlowStatus] 
     ,[CTE].[Status] -- This will display the human name on the front-end with code. 
     ,[Users].[F7] AS [ResponsibilityName] 
     ,[GroupName].[Name] AS [AppGroupName] 
     ,[AppName].[Name] AS [AppName] 
FROM 
      CTE 
LEFT JOIN [S3] [Users] ON [Users].[F0] = [CTE].[Responsibility] 
LEFT JOIN [GroupName] ON [GroupName].[ViewID] = [CTE].[ViewID] 
LEFT JOIN [AppName]  ON [AppName].[ItemID] = [CTE].[FolderItemID]