在 CTE 中实现标量函数
Posted
技术标签:
【中文标题】在 CTE 中实现标量函数【英文标题】:Implement the Scalar Function inside a CTE 【发布时间】:2019-08-16 06:57:04 【问题描述】:我有一个视图(视图中包含一个 CTE,如下所示),其中我调用了一个标量函数,而在同一个标量函数中调用了视图。这整个过程使性能变慢。我可以在同一个视图中实现函数的功能吗? 请帮忙
WITH tree AS
(
SELECT c1.structureid,c1.assessmentid, c1.sequence,c1.Required,c1.Objective, c1.parentid, c1.Text, [level] = 1, path = cast( c1.structureid as varchar(100))
FROM [ast].[Structure] c1
WHERE c1.parentid IS NULL
UNION ALL
SELECT c2.structureid, c2.assessmentid, c2.sequence,c2.Required,c2.Objective, c2.parentid, c2.Text, [level] = tree.[level] + 1,
Path = Cast(tree.path+'/'+right('000000000' + cast(c2.structureid as varchar(10)),10) as varchar(100))
FROM [ast].[Structure] c2 INNER JOIN tree ON tree.structureid = c2.parentid
)
SELECT tree.level,tree.sequence,
tree.path, parentid, tree.assessmentid, tree.Required,tree.Objective, (SELECT [dbo].Tree_full_index(tree.structureid))+' '+ tree.Text AS description ,C.* ,
wasScored = (case when C.choiceid is null then 0 else 1 end ),
wasDerived = (case when C.choiceid is null and C.Score is not null then 1 else 0 end )
FROM tree inner join [ast].[Value] as C on tree.structureid = C.structureid
标量函数
ALTER FUNCTION [dbo].[Tree_full_index]
(
@tree_node_id int
)
RETURNS varchar(20)
AS
BEGIN
declare @result varchar(20)
set @result =''
declare @node_seq_index varchar(5)
DECLARE @parentID int
select @node_seq_index=isnull(sequence,''),@parentID=isnull(parentid,0) from vwAssesment where structureid=@tree_node_id
set @result=@node_seq_index
WHILE @parentID > 0
BEGIN
SELECT @tree_node_id = @parentID
select @node_seq_index=isnull(sequence,''),@parentID=parentid from vwAssesment where structureid=@tree_node_id
set @result=@node_seq_index+'.0'+@result
END
RETURN @result
END
结构表
StructureId AssessmentId ParentId Required Sequence Text Objective
633 132 NULL 1 1 Customer Satisfaction understand our top Customers and our supplier ranking with them.
634 132 633 1 1 Top Customers NULL
635 132 634 1 1 Display top Customers on Lead Board NULL
636 132 634 1 2 Display Customer Supplier Ranking for Facility - NA NULL
637 132 634 1 3 Display Work Plan that provides path to Preferred Supplier status NULL
638 132 633 1 2 Real Time Response Process NULL
639 132 638 0 1 Real-time response system in place when abnormalities occur with documented Counter Measures NULL
640 132 NULL 1 2 Continuous Improvement ensure driving foundation for Continuous Improvement
641 132 640 1 1 Gemba NULL
642 132 641 1 1 Routine and scheduled NULL
643 132 641 1 2 Incorporated into appropriate different levels of organization NULL
644 132 640 1 2 TPM NULL
645 132 644 1 1 Perform initial Cleaning & Inspection (Level 1) NULL
646 132 645 1 1 Learn how to identify equipment problems NULL
结果应该有如图所示的节点实际索引的列
level sequence parentid assessmentid Required Objective description ValueId InstanceId StructureId ChoiceId Score wasScored wasDerived
1 1 NULL 132 1 understand our top Customers and our supplier ranking with them. Ensure In-Station Quality and continuous improvement. 1 Customer Satisfaction 666 207 633 NULL 2 0 1
2 1 633 132 1 NULL 1.01 Top Customers 667 207 634 NULL 4 0 1
3 1 634 132 1 NULL 1.01.01 Display top Customers on Lead Board 668 207 635 40 4 1 0
3 2 634 132 1 NULL 1.01.02 Display Customer Supplier Ranking for Facility - NA 669 207 636 40 4 1 0
3 3 634 132 1 NULL 1.01.03 Display Work Plan that provides path to Preferred Supplier status 670 207 637 40 4 1 0
2 2 633 132 1 NULL 1.02 Real Time Response Process 671 207 638 NULL NULL 0 0
3 1 638 132 0 NULL 1.02.01 Real-time response system in place when abnormalities occur with documented Counter Measures 672 207 639 NULL NULL 0 0
1 2 NULL 132 1 ensure driving foundation for Continuous Improvement culture to be successful and achieve meaningful results 2 Continuous Improvement 673 207 640 NULL 3.5 0 1
2 1 640 132 1 NULL 2.01 Gemba 674 207 641 20 2 1 0
3 1 641 132 1 NULL 2.01.01 Routine and scheduled 675 207 642 NULL NULL 0 0
3 2 641 132 1 NULL 2.01.02 Incorporated into appropriate different levels of organization (Facility Manager, Staff, site Director) 676 207 643 NULL NULL 0 0
2 2 640 132 1 NULL 2.02 TPM 677 207 644 NULL 5 0 1
3 1 644 132 1 NULL 2.02.01 Perform initial Cleaning & Inspection (Level 1) 678 207 645 50 5 1 0
4 1 645 132 1 NULL 2.02.01.01 Learn how to identify equipment problems 679 207 646 NULL NULL 0 0
【问题讨论】:
请格式化您的问题。不可读 在每行调用一次的标量函数中的 While 循环并不好。我会开始尝试删除它。 乍一看我会说你可以用递归 CTE 替换标量函数。 如果这是您想要的,请您将下面的答案标记为您问题的答案。 【参考方案1】:您可以在视图中或树cte之前的CTE中实现该功能,如下所示:-
;with prev as (
select *,1 [depth],cast(isnull([sequence],'') as varchar(max)) [Tree_full_index] From vwAssesment where parentid is null
union all
select v.*,prev.depth+1 [depth],+[Tree_full_index]+'.0'+isnull(v.[sequence],'') from prev
inner join vwAssesment v on v.parentid=prev.structureid
),Tree as (.......
我测试了 prev cte,它将 Tree_full_index 作为 vwAssesment 的所有列的一部分返回,因此将查询更改为使用 prev 而不是 vwAssesment,或者更新 vwAssesment 或创建一个新视图以拥有 Tree_full_index 并使用它
对于以下示例数据:-
Declare @vwAssesment Table(
structureid int,
parentid int,
[sequence] varchar(5)
)
insert into @vwAssesment values(1,null,'1')
insert into @vwAssesment values(2,null,'2')
insert into @vwAssesment values(3,null,'3')
insert into @vwAssesment values(4,1, '1')
insert into @vwAssesment values(5,1, '2')
insert into @vwAssesment values(6,1, '3')
insert into @vwAssesment values(7,2, '2')
insert into @vwAssesment values(8,2, '3')
insert into @vwAssesment values(9,8, '2')
insert into @vwAssesment values(10,8,'3')
结果是:-
structureid parentid sequence depth Tree_full_index
1 NULL 1 1 1
2 NULL 2 1 2
3 NULL 3 1 3
4 1 1 2 1.01
5 1 2 2 1.02
6 1 3 2 1.03
7 2 2 2 2.02
8 2 3 2 2.03
9 8 2 3 2.03.02
10 8 3 3 2.03.03
【讨论】:
太好了,如果这是您正在寻找的答案,请您将其标记为答案。以上是关于在 CTE 中实现标量函数的主要内容,如果未能解决你的问题,请参考以下文章