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