我有OutputTemplates - > OutputBookmarks - > OutputNodes - > OutputTemplates - > OutputBookmarks - > OutputNodes ......等
我从一组已知的OutputTemplate中的顶级OutputNodes开始 - > OutputBookmarks
我希望简化下面的查询以获取所有子OutputNodeID和性能。
ALTER PROCEDURE [促销]。[Promote_Outputs_Delete_Output_Nodes_Not_In_Source](@ promotionID UNIQUEIDENTIFIER) 如 BEGIN
WITH
CTE_OutputOptions
AS (
SELECT t.p.value('@OutputOptionID', 'uniqueidentifier') AS OutputOptionID,
t.p.value('@TemplateID', 'uniqueidentifier') AS OutputTemplateID
FROM [Promotion].Promotions AS p
CROSS APPLY p.OutputsXml.nodes('/Data/dbo.OutputOptions/dbo.OutputOptions') t(p)
INNER JOIN [dbo].[OutputOptions] oo
ON oo.OutputOptionID = t.p.value('@OutputOptionID', 'uniqueidentifier')
WHERE p.PromotionID = @promotionID)
,CTE_AllSourceOutputTemplates
AS (
SELECT t.p.value('@OutputTemplateID', 'uniqueidentifier') AS OutputTemplateID,
t.p.value('@TemplateFileName', 'nvarchar(200)') AS TemplateFileName,
t.p.value('@CreatedDate', 'datetime') AS CreatedDate,
coalesce(t.p.value('@CreatedByUserID', 'uniqueidentifier'), '00000000-0000-0000-0000-000000000000') AS CreatedByUserID,
t.p.value('@DeletedDate', 'datetime') AS DeletedDate,
t.p.value('@DeletedByUserID', 'uniqueidentifier') AS DeletedByUserID,
t.p.value('@ModifiedByUserID', 'uniqueidentifier') AS ModifiedByUserID,
t.p.value('@ModifiedDate', 'datetime') AS ModifiedDate,
t.p.value('@IOFileName', 'nvarchar(100)') AS IOFileName
FROM [Promotion].Promotions AS p
CROSS APPLY p.OutputsXml.nodes('/Data/Outputs.OutputTemplates/Outputs.OutputTemplates') t(p)
WHERE p.PromotionID = @promotionID)
,CTE_AllSourceBookmarks
AS (
SELECT t.p.value('@OutputDocTemplateBookmarkID', 'uniqueidentifier') AS OutputDocTemplateBookmarkID,
t.p.value('@OutputTemplateID', 'uniqueidentifier') AS OutputTemplateID,
t.p.value('@OutputDocBookmarkTypeID', 'int') AS OutputDocBookmarkTypeID,
t.p.value('@Name', 'nvarchar(200)') AS Name,
t.p.value('@DisplayOrder', 'int') AS DisplayOrder,
t.p.value('@DoPageBreakBefore', 'bit') AS DoPageBreakBefore,
t.p.value('@DoPageBreakAfter', 'bit') AS DoPageBreakAfter,
t.p.value('@SoftName', 'nvarchar(100)') AS SoftName,
t.p.value('@ShowOnOverridePage', 'bit') AS ShowOnOverridePage,
t.p.value('@AllowVisibilityOverride', 'bit') AS AllowVisibilityOverride,
t.p.value('@AllowForcePageBreak', 'bit') AS AllowForcePageBreak,
t.p.value('@ShowOnAllVersions', 'bit') AS ShowOnAllVersions,
t.p.value('@DefaultToHidden', 'bit') AS DefaultToHidden
FROM [Promotion].Promotions AS p
CROSS APPLY p.OutputsXml.nodes('/Data/Outputs.OutputDocTemplateBookmarks/Outputs.OutputDocTemplateBookmarks') t(p)
WHERE p.PromotionID = @promotionID)
,CTE_AllSourceOutputNodes
AS (
SELECT t.p.value('@OutputNodeID', 'uniqueidentifier') AS OutputNodeID,
t.p.value('@OutputNodeTypeID', 'int') AS OutputNodeTypeID,
t.p.value('@OutputTemplateID', 'uniqueidentifier') AS OutputTemplateID,
t.p.value('@OutputTemplateBookmarkID', 'uniqueidentifier') AS OutputDocTemplateBookmarkID,
t.p.value('@LinkedToNodeID', 'uniqueidentifier') AS LinkedToNodeID
FROM [Promotion].Promotions AS p
CROSS APPLY p.OutputsXml.nodes('/Data/Outputs.OutputNodes/Outputs.OutputNodes') t(p)
WHERE
p.PromotionID = @promotionID)
,CTE_TopSourceOutputTemplates
AS (
SELECT aot.OutputTemplateID,
TemplateFileName,
CreatedDate,
CreatedByUserID,
DeletedDate,
DeletedByUserID,
ModifiedByUserID,
ModifiedDate,
IOFileName
FROM CTE_AllSourceOutputTemplates aot
INNER JOIN CTE_OutputOptions opts
ON opts.OutputTemplateID = aot.OutputTemplateID
)
,CTE_TopSourceBookmarks
AS (
SELECT OutputDocTemplateBookmarkID,
ab.OutputTemplateID,
OutputDocBookmarkTypeID,
Name,
DisplayOrder,
DoPageBreakBefore,
DoPageBreakAfter,
SoftName,
ShowOnOverridePage,
AllowVisibilityOverride,
AllowForcePageBreak,
ShowOnAllVersions,
DefaultToHidden
FROM CTE_AllSourceBookmarks ab
INNER JOIN CTE_TopSourceOutputTemplates toptemplates
ON ab.OutputTemplateID = toptemplates.OutputTemplateID
)
,CTE_TopSourceOutputNodes
AS (
SELECT allsourcenodes.OutputNodeID,
allsourcenodes.OutputNodeTypeID,
allsourcenodes.OutputTemplateID,
allsourcenodes.OutputDocTemplateBookmarkID,
allsourcenodes.LinkedToNodeID
FROM CTE_AllSourceOutputNodes allsourcenodes
INNER JOIN CTE_TopSourceBookmarks topbookmarks
ON allsourcenodes.OutputDocTemplateBookmarkID = topbookmarks.OutputDocTemplateBookmarkID
)
,CTE_NextOutputTemplates1
AS (
SELECT aot.OutputTemplateID,
TemplateFileName,
CreatedDate,
CreatedByUserID,
DeletedDate,
DeletedByUserID,
ModifiedByUserID,
ModifiedDate,
IOFileName
FROM CTE_AllSourceOutputTemplates aot
INNER JOIN CTE_TopSourceOutputNodes topnodes
ON topnodes.OutputTemplateID = aot.OutputTemplateID
),
CTE_NextOutputBookmarks1
AS (
SELECT OutputDocTemplateBookmarkID,
ab.OutputTemplateID,
OutputDocBookmarkTypeID,
Name,
DisplayOrder,
DoPageBreakBefore,
DoPageBreakAfter,
SoftName,
ShowOnOverridePage,
AllowVisibilityOverride,
AllowForcePageBreak,
ShowOnAllVersions,
DefaultToHidden
FROM CTE_AllSourceBookmarks ab
INNER JOIN CTE_NextOutputTemplates1 nexttemplates
ON ab.OutputTemplateID = nexttemplates.OutputTemplateID
),
CTE_NextOutputNodes1
AS (
SELECT allsourcenodes.OutputNodeID,
allsourcenodes.OutputNodeTypeID,
allsourcenodes.OutputTemplateID,
allsourcenodes.OutputDocTemplateBookmarkID,
allsourcenodes.LinkedToNodeID
FROM CTE_AllSourceOutputNodes allsourcenodes
INNER JOIN CTE_NextOutputBookmarks1 nextbookmarks
ON allsourcenodes.OutputDocTemplateBookmarkID = nextbookmarks.OutputDocTemplateBookmarkID
)
--------
,CTE_NextOutputTemplates2
AS (
SELECT aot.OutputTemplateID,
TemplateFileName,
CreatedDate,
CreatedByUserID,
DeletedDate,
DeletedByUserID,
ModifiedByUserID,
ModifiedDate,
IOFileName
FROM CTE_AllSourceOutputTemplates aot
INNER JOIN CTE_NextOutputNodes1 nextnodes
ON nextnodes.OutputTemplateID = aot.OutputTemplateID
),
CTE_NextOutputBookmarks2
AS (
SELECT OutputDocTemplateBookmarkID,
ab.OutputTemplateID,
OutputDocBookmarkTypeID,
Name,
DisplayOrder,
DoPageBreakBefore,
DoPageBreakAfter,
SoftName,
ShowOnOverridePage,
AllowVisibilityOverride,
AllowForcePageBreak,
ShowOnAllVersions,
DefaultToHidden
FROM CTE_AllSourceBookmarks ab
INNER JOIN CTE_NextOutputTemplates2 nexttemplates
ON ab.OutputTemplateID = nexttemplates.OutputTemplateID
),
CTE_NextOutputNodes2
AS (
SELECT allsourcenodes.OutputNodeID,
allsourcenodes.OutputNodeTypeID,
allsourcenodes.OutputTemplateID,
allsourcenodes.OutputDocTemplateBookmarkID,
allsourcenodes.LinkedToNodeID
FROM CTE_AllSourceOutputNodes allsourcenodes
INNER JOIN CTE_NextOutputBookmarks2 nextbookmarks
ON allsourcenodes.OutputDocTemplateBookmarkID = nextbookmarks.OutputDocTemplateBookmarkID
)
----------------------
,CTE_NextOutputTemplates3
AS (
SELECT aot.OutputTemplateID,
TemplateFileName,
CreatedDate,
CreatedByUserID,
DeletedDate,
DeletedByUserID,
ModifiedByUserID,
ModifiedDate,
IOFileName
FROM CTE_AllSourceOutputTemplates aot
INNER JOIN CTE_NextOutputNodes2 nextnodes
ON nextnodes.OutputTemplateID = aot.OutputTemplateID
),
CTE_NextOutputBookmarks3
AS (
SELECT OutputDocTemplateBookmarkID,
ab.OutputTemplateID,
OutputDocBookmarkTypeID,
Name,
DisplayOrder,
DoPageBreakBefore,
DoPageBreakAfter,
SoftName,
ShowOnOverridePage,
AllowVisibilityOverride,
AllowForcePageBreak,
ShowOnAllVersions,
DefaultToHidden
FROM CTE_AllSourceBookmarks ab
INNER JOIN CTE_NextOutputTemplates3 nexttemplates
ON ab.OutputTemplateID = nexttemplates.OutputTemplateID
),
CTE_NextOutputNodes3
AS (
SELECT allsourcenodes.OutputNodeID,
allsourcenodes.OutputNodeTypeID,
allsourcenodes.OutputTemplateID,
allsourcenodes.OutputDocTemplateBookmarkID,
allsourcenodes.LinkedToNodeID
FROM CTE_AllSourceOutputNodes allsourcenodes
INNER JOIN CTE_NextOutputBookmarks3 nextbookmarks
ON allsourcenodes.OutputDocTemplateBookmarkID = nextbookmarks.OutputDocTemplateBookmarkID
)
-------------------------------------
,CTE_NextOutputTemplates4
AS (
SELECT aot.OutputTemplateID,
TemplateFileName,
CreatedDate,
CreatedByUserID,
DeletedDate,
DeletedByUserID,
ModifiedByUserID,
ModifiedDate,
IOFileName
FROM CTE_AllSourceOutputTemplates aot
INNER JOIN CTE_NextOutputNodes3 nextnodes
ON nextnodes.OutputTemplateID = aot.OutputTemplateID
),
CTE_NextOutputBookmarks4
AS (
SELECT OutputDocTemplateBookmarkID,
ab.OutputTemplateID,
OutputDocBookmarkTypeID,
Name,
DisplayOrder,
DoPageBreakBefore,
DoPageBreakAfter,
SoftName,
ShowOnOverridePage,
AllowVisibilityOverride,
AllowForcePageBreak,
ShowOnAllVersions,
DefaultToHidden
FROM CTE_AllSourceBookmarks ab
INNER JOIN CTE_NextOutputTemplates4 nexttemplates
ON ab.OutputTemplateID = nexttemplates.OutputTemplateID
),
CTE_NextOutputNodes4
AS (
SELECT allsourcenodes.OutputNodeID,
allsourcenodes.OutputNodeTypeID,
allsourcenodes.OutputTemplateID,
allsourcenodes.OutputDocTemplateBookmarkID,
allsourcenodes.LinkedToNodeID
FROM CTE_AllSourceOutputNodes allsourcenodes
INNER JOIN CTE_NextOutputBookmarks4 nextbookmarks
ON allsourcenodes.OutputDocTemplateBookmarkID = nextbookmarks.OutputDocTemplateBookmarkID
)
------------------------------
,CTE_NextOutputTemplates5
AS (
SELECT aot.OutputTemplateID,
TemplateFileName,
CreatedDate,
CreatedByUserID,
DeletedDate,
DeletedByUserID,
ModifiedByUserID,
ModifiedDate,
IOFileName
FROM CTE_AllSourceOutputTemplates aot
INNER JOIN CTE_NextOutputNodes4 nextnodes
ON nextnodes.OutputTemplateID = aot.OutputTemplateID
),
CTE_NextOutputBookmarks5
AS (
SELECT OutputDocTemplateBookmarkID,
ab.OutputTemplateID,
OutputDocBookmarkTypeID,
Name,
DisplayOrder,
DoPageBreakBefore,
DoPageBreakAfter,
SoftName,
ShowOnOverridePage,
AllowVisibilityOverride,
AllowForcePageBreak,
ShowOnAllVersions,
DefaultToHidden
FROM CTE_AllSourceBookmarks ab
INNER JOIN CTE_NextOutputTemplates5 nexttemplates
ON ab.OutputTemplateID = nexttemplates.OutputTemplateID
),
CTE_NextOutputNodes5
AS (
SELECT allsourcenodes.OutputNodeID,
allsourcenodes.OutputNodeTypeID,
allsourcenodes.OutputTemplateID,
allsourcenodes.OutputDocTemplateBookmarkID,
allsourcenodes.LinkedToNodeID
FROM CTE_AllSourceOutputNodes allsourcenodes
INNER JOIN CTE_NextOutputBookmarks5 nextbookmarks
ON allsourcenodes.OutputDocTemplateBookmarkID = nextbookmarks.OutputDocTemplateBookmarkID
)
select * from CTE_NextOutputNodes5 --where outputtemplateid is not null
UNION
SELECT * from CTE_NextOutputNodes4
UNION
SELECT * from CTE_NextOutputNodes3
UNION
SELECT * from CTE_NextOutputNodes2
UNION
SELECT * from CTE_NextOutputNodes1
UNION
SELECT * from CTE_TopSourceOutputNodes
END
- 最终 - 这有效
WITH
CTE_RecursiveTemplateBookmarkNodes AS
(
select t.outputtemplateid, b.outputdoctemplatebookmarkid, n.outputnodeid, n.outputtemplateid as nodetemplateid
from outputs.outputtemplates t
inner join outputs.OutputDocTemplateBookmarks b
on t.outputtemplateid = b.outputtemplateid
inner join outputs.outputnodes n
on b.outputdoctemplatebookmarkid = n.outputtemplatebookmarkid
UNION ALL
select t.outputtemplateid, b.outputdoctemplatebookmarkid, n.outputnodeid, n.outputtemplateid as nodetemplateid
from CTE_RecursiveTemplateBookmarkNodes cte
inner join outputs.outputtemplates t
on t.outputtemplateid = cte.nodetemplateid
inner join outputs.outputdoctemplatebookmarks b
on b.OutputTemplateID = t.outputtemplateid
inner join outputs.outputnodes n
on b.outputdoctemplatebookmarkid = n.outputtemplatebookmarkid
)
select distinct * from CTE_RecursiveTemplateBookmarkNodes
答案 0 :(得分:1)
下面是一个脚本,其中包含示例数据和带有想法的查询,您可以将其应用于您的问题。该脚本可以按原样运行。如果您需要,我可以尝试为您的问题编写确切的查询,但我需要一个用于查询的XML示例。
-- sample data
declare @templates xml = '<root>
<template id="1"></template>
<template id="2"></template>
<template id="3"></template>
<template id="4"></template>
<template id="5"></template>
</root>'
declare @bookmarks xml = '<root>
<bookmark id="1" templateId="1"></bookmark>
<bookmark id="2" templateId="2"></bookmark>
<bookmark id="3" templateId="3"></bookmark>
<bookmark id="4" templateId="4"></bookmark>
<bookmark id="5" templateId="5"></bookmark>
</root>'
declare @nodes xml = '<root>
<node id="1" bookmarkId="1" templateId="2"></node>
<node id="2" bookmarkId="1" templateId="3"></node>
<node id="3" bookmarkId="2" templateId="4"></node>
<node id="4" bookmarkId="3" templateId="5"></node>
<node id="5" bookmarkId="4"></node>
<node id="6" bookmarkId="5"></node>
</root>'
-- query
;with alltemplates as (
select id = a.value('@id', 'int') from @templates.nodes('/root/template') a(a)
),allbookmarks as (
select id = a.value('@id', 'int'), templateId = a.value('@templateId', 'int') from @bookmarks.nodes('/root/bookmark') a(a)
),allnodes as (
select id = a.value('@id', 'int'), bookmarkId = a.value('@bookmarkId', 'int'), templateId = a.value('@templateId', 'int') from @nodes.nodes('/root/node') a(a)
), cte as (
select nodeId = allnodes.id, allnodes.templateId from alltemplates
join allbookmarks on alltemplates.id = allbookmarks.templateId
join allnodes on allbookmarks.id = allnodes.bookmarkId
where alltemplates.id = 1 -- join on options instead
union all
select allnodes.id, allnodes.templateId from cte
join allbookmarks on cte.templateId = allbookmarks.templateId
join allnodes on allbookmarks.id = allnodes.bookmarkId
)
select nodeId from cte