2011-12-06 19 views
11

Có thể thực hiện truy vấn phụ JOIN với một biểu thức bảng chung không? Nếu không, sau đó ai đó có thể cho tôi biết làm thế nào để thực hiện những gì tôi đang cố gắng để làm dưới đây? Ví dụ sẽ là tuyệt vời.T-SQL THAM GIA đối với một biểu thức bảng chung (CTE)

Ví dụ:

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] 

Đây là truy vấn đầy đủ của tôi:

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

Cảm ơn rất nhiều!

Trả lời

30

Khi bạn xác định CTE bạn đang làm như vậy trước bất kỳ phần còn lại của truy vấn. Vì vậy, bạn không thể viết:

LEFT JOIN (
    ;WITH CTE 
    ... 
) 

Như một cách nhanh chóng sang một bên, lý do người đặt ; trước WITH là bởi vì tất cả các báo cáo trước đó cần phải được chấm dứt. Nếu các nhà phát triển có thể nhận được trong thói quen chấm dứt tất cả các câu lệnh SQL với ; sau đó nó sẽ không cần thiết, nhưng tôi lạc đề ...

Bạn có thể viết nhiều CTEs như vậy:

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

Và miễn là một CTE được xác định trước những người khác, nó có thể được giới thiệu trong các CTE theo sau. – Bora

1

Bạn có thể có nhiều CTE, tôi tin; bạn chỉ cần đặt cả hai ở trên cùng.

Xem here:

Bạn có thể, tuy nhiên, xác định nhiều CTEs sau VỚI từ khóa bằng cách tách từng CTE bằng dấu phẩy.

2

Nếu bạn có nhiều CTE, họ cần phải được ở phần đầu của tuyên bố của bạn (bằng dấu phẩy, và chỉ có một ;WITH để bắt đầu danh sách các CTE của):

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

và sau đó bạn có thể sử dụng cả hai (hoặc thậm chí nhiều hơn hai) trong tuyên bố SELECT của bạn.

3

Nhiều CTE cần được khai báo trước. Ví dụ:

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] 
Các vấn đề liên quan