I have [dbo].[fn_GetUserPublications] function which return information about User's publications. It returns fields like Title, Desctiption, CreatedDate, etc. It does not return any information about parent/child relationships. This is my main datasource actually.
My goal is to build some kind of hierarchy. That is why i created a [Source] CTE which populates ParentPublicationID.
But i want to extend this datasource with two additional fields:
Here is what i did:
WITH [Source] AS
(
SELECT
[UserPublication].*,
[Publication].[ParentPublicationID] AS [ParentPublicationID]
FROM
[dbo].[fn_GetUserPublications](@userId) AS [UserPublication]
INNER JOIN [dbo].[Publication] AS [Publication] ON
[UserPublication].[ID] = [Publication].[ID]
),
[SourceWithParent] AS
(
SELECT DISTINCT
[SourcePublication].ID,
[ParentPublication].[UID] AS [ParentUID]
FROM
[Source] AS [SourcePublication]
INNER JOIN [Source] AS [ParentPublication] ON
[ParentPublication].[ID] = [SourcePublication].[ParentPublicationID]
INNER JOIN [dbo].[Publication] AS [Publication] ON
[Publication].[ID] = [ParentPublication].[ID]
),
[SourceWithChildren] AS
(
SELECT DISTINCT
[SourcePublication].[ID],
CAST (
CASE
WHEN COUNT([ChildPublication].[ID]) > 0
THEN 1
ELSE 0
END
AS bit
) AS [HasChildren]
FROM
[Source] AS [SourcePublication]
LEFT JOIN [Source] AS [ChildPublication] ON
[ChildPublication].[ParentPublicationID] = [SourcePublication].[ID]
GROUP BY [SourcePublication].[ID]
)
SELECT
[Source].*,
[SourceWithParent].[ParentUID],
[SourceWithChildren].[HasChildren]
FROM
[Source]
LEFT JOIN [SourceWithParent] ON
[SourceWithParent].[ID] = [Source].[ID]
LEFT JOIN [SourceWithChildren] ON
[SourceWithChildren].[ID] = [Source].[ID]
This code works but there is one problem. My fn_GetUserPublications function is called 5 times in this script (probably because Source CTE is called 5 times). This is the beginning of the execution plan. Can't attach full plan because it's quite big and it contains some names from my PROD database. But it shows that he same function was called 5 times
How can i achieve the same by calling fn_GetUserPublications function only once (by calling CTE once) and then just reusing the output?
Insert the function output into a #temp table and join to that. SQL Server doesn't have a SPOOL/CACHE/MATERIALIZE query hint.
eg
SELECT
[UserPublication].*,
[Publication].[ParentPublicationID] AS [ParentPublicationID]
INTO #SOURCE
FROM
[dbo].[fn_GetUserPublications](@userId) AS [UserPublication]
INNER JOIN [dbo].[Publication] AS [Publication] ON
[UserPublication].[ID] = [Publication].[ID];
WITH [Source] AS
(
SELECT * FROM #SOURCE
), . . .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.