Соединение T-SQL с общим табличным выражением (CTE)
можно ли выполнить запрос JOIN sub для общего табличного выражения? Если нет, то может ли кто-нибудь дать мне знать, как выполнить то, что я пытаюсь сделать ниже? Примеры были бы превосходны.
например:
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)
спасибо!
5 ответов
когда вы определяете CTE, вы делаете это перед любым из остальных запросов. Поэтому вы не можете написать:
LEFT JOIN (
;WITH CTE
...
)
как быстро в сторону,причина люди ставят ;
перед WITH
потому что все предыдущие операторы должны быть прекращены. Если бы разработчики могли привыкнуть завершать все операторы SQL с помощью ;
тогда в этом не было бы необходимости, но я отвлекся...
вы можете написать несколько CTEs, как так:
WITH SomeCTE AS (
SELECT ...
FROM ...
), AnotherCTE AS (
SELECT ...
FROM ...
)
SELECT *
FROM SomeCTE LEFT JOIN
AnotherCTE ON ...
;
сначала необходимо объявить несколько CTE. Пример:
WITH CTE_1 AS
(
....
),
CTE_2 AS
(
...
)
SELECT *
FROM FOO
LEFT JOIN CTE_1
LEFT JOIN CTE_2
Если у вас есть несколько CTE, они должны быть в начале вашего заявления (через запятую, и только один ;WITH
чтобы начать список CTE):
;WITH CTE AS (......),
[UserDefined] AS (.......)
SELECT.....
и затем вы можете использовать оба (или даже более двух) в вашей SELECT
заявление.
У вас может быть несколько CTEs, я считаю; вы просто должны поместить их обоих наверху.
посмотреть здесь:
вы можете, однако, определить несколько CTEs после ключевого слова WITH, разделив каждый CTE запятой.
;
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]