在每条记录上调用递归CTE

时间:2016-06-21 07:17:11

标签: sql sql-server sql-server-2008 common-table-expression

我有一个存储过程查询,它将与其位置相关的所有电气面板返回到给定的电路。为了使查询尽可能地提供信息,我还返回每个面板上的负载(电路功率要求之和)和所用电路的数量。

每个面板的加载总和必须考虑面板之间的父子关系,因为一些面板提供其他也有负载的面板。

要实现此父子加载计算,我使用递归CTE,它可以很好地找到1个面板的负载。但是,当我想使用第一个查询时,它会在每一行调用CTE计算查询,从而导致显着的性能损失。

为了加快此查询,最佳做法是什么?我已经尝试过有用的表值函数,但我觉得我需要一种完全不同的方法。

主要查询

SELECT p.Panel,
       (ABS(gcX.COOR -t.TX) + ABS(gcY.COOR -t.TY)) / 1000 AS Length,
       'TBD' AS Load,
       'TBD' AS [Available Circuits],
       ROUND(v.kVA / p.kVA * 100, 0) AS LOAD,
       p.[Status],
       p.PanelID
  FROM 
  (
     SELECT poc.*,
            tc.X,
            tc.Y
       FROM tblPowerCircuits poc   
       LEFT JOIN SI_EquipCoordinates tc
         ON poc.EntityCode = tc.Entity_Code
            AND  poc.Life = tc.Life
      WHERE poc.POCID = @POCID
  )t
  INNER JOIN tblPanels p
     ON t.utility = p.Utility
        AND t.train = p.train
        AND t.Filt = p.Filt
        AND p.BP_DP =
            CASE 
                WHEN t.FLA < 61 THEN 1
                ELSE 2
            END
        AND p.voltage =
            CASE
              WHEN t.voltage = 230 THEN 400
              WHEN t.voltage = 120 THEN 208
              ELSE t.voltage
            END
   LEFT JOIN SI_GridCoordinates gcX
     ON p.x = gcX.GRID
        AND p.Facility = gcX.FAB   
   LEFT JOIN SI_GridCoordinates gcY
     ON p.y = gcY.GRID
        AND p.Facility = gcY.FAB   
  CROSS APPLY dbo.fnPH_GetPanelLoad(p.PanelID)v
  WHERE p.VisibleToFilter = 1
  ORDER BY Length, panel

按面板加载查询

SET QUOTED_IDENTIFIER ON
GO
ALTER function [dbo].[fnPH_GetPanelLoad](
@PanelID int
)
returns table
as

return
( Select vpc.SourceID, round((Sum(poc.KVA * (CASE WHEN vpc.BP_DP = 1 THEN 0.8 * POWER(CAST(0.8 AS float), Depth) WHEN vpc.BP_DP = 2 THEN 0.64 * POWER(CAST(0.8 AS float), Depth) END))),0) as kVA from vwPanelClosure vpc join
PH_PanelCircuits pc on vpc.PanelID = pc.PanelID join
(Select * from PH_POCPanJoin where Active = 1) pj on pc.PanCctID = pj.PanCctID join
(SELECT        POCID, Circuit, L,F, KVA, Active
                               FROM            dbo.tblPowerCircuits) AS poc ON pj.POCID = poc.POCID LEFT OUTER JOIN                
                             (SELECT        Circuit, InstallDate,DemoDate
                               FROM            dbo.PH_POC_InstallDeinstallDate) AS s ON poc.Circuit = s.[Circuit] AND poc.L= s.L where (s.DemoDate > Dateadd(d,830,getdate()) or s.DemoDate is null) and vpc.sourceID = @PanelID
 group by

vpc.SourceID)

这是递归查询vwPanelClosure

WITH category_cte AS (SELECT        PanelID AS SourceID, PanelID, BP_DP, 0 AS depth
                                                  FROM            dbo.tblPanels
                                                  UNION ALL
                                                  SELECT        CTE.SourceID, C.PanelID, C.BP_DP, CTE.depth + 1 AS depth
                                                  FROM            dbo.tblPanels AS C INNER JOIN
                                                                           category_cte AS CTE ON C.SCID = CTE.PanelID)
    SELECT        SourceID, PanelID, BP_DP, depth
     FROM            category_cte AS category_cte_1

我应该使用类似#Temp表的内容来存储重复处理的CTE值吗?

0 个答案:

没有答案