如何使用CTE

时间:2019-04-04 16:15:45

标签: sql-server common-table-expression hierarchical-data

我有一组复杂的数据库行,它们通过关联表以库存管理系统的父/子关系连接。父级由子级组成,子级也可以由子级子级创建,依此类推。此外,孩子可以有多个父母(例如,许多物品都使用螺丝,并且是所有这些物品的孩子)。

我已经使用CTE创建了一个查询,该查询将查找起始节点的所有父级,然后向下搜索所有父级,以找到相关父级下的所有子级。但是,这并不能使所有潜在的连接节点都到达原始项目。这是因为当您从起点横向扩展时,所连接节点的每次潜在扫描都可能添加一些尚未发现的父级或子级。我尝试添加更多的CTE块,这些块将获得先前的结果并再次连接,但是经过几次迭代后,开始变得非常缓慢。根据我的客户数据,前几个周期很快,但是第4轮需要24秒,第5轮需要12分钟。

这是我一直在测试的示例查询,其深度为5个CTE级别。

;WITH cte 
  AS (SELECT a.itemid 
        FROM item a 
       WHERE a.itemid = 1732 
       UNION ALL 
      SELECT a.itemid 
        FROM item a 
        JOIN assemblylineitem b 
          ON a.itemid = b.itemid 
        JOIN cte c 
          ON b.componentitemid = c.itemid), 
cte2 
  AS (SELECT a.itemid
        FROM item a 
       WHERE a.itemid IN (SELECT itemid FROM cte) 
       UNION ALL 
      SELECT a.itemid 
        FROM item a 
        JOIN assemblylineitem b 
          ON a.itemid = b.componentitemid 
        JOIN cte c 
          ON b.itemid = c.itemid),
cte3 
  AS (SELECT a.itemid 
        FROM item a 
       WHERE a.itemid in (SELECT itemid FROM cte2)
       UNION ALL 
      SELECT a.itemid 
        FROM item a 
        JOIN assemblylineitem b 
          ON a.itemid = b.itemid 
        JOIN cte2 c 
          ON b.componentitemid = c.itemid), 
cte4 
  AS (SELECT a.itemid
        FROM item a 
       WHERE a.itemid IN (SELECT itemid FROM cte3) 
       UNION ALL 
      SELECT a.itemid 
        FROM item a 
        JOIN assemblylineitem b 
          ON a.itemid = b.componentitemid 
        JOIN cte3 c 
          ON b.itemid = c.itemid),
cte5
  AS (SELECT a.itemid 
        FROM item a 
       WHERE a.itemid in (SELECT itemid FROM cte4)
       UNION ALL 
      SELECT a.itemid 
        FROM item a 
        JOIN assemblylineitem b 
          ON a.itemid = b.itemid 
        JOIN cte4 c 
          ON b.componentitemid = c.itemid)

SELECT distinct(itemid)
FROM   cte5
order by itemid

是否有一种结构化查询的方法,该查询会将所有潜在的连接节点连接到起点,并且性能良好?

0 个答案:

没有答案