是否存在基于集合的解决方案,用于在多行上执行rCTE?

时间:2014-07-15 23:26:50

标签: sql-server-2012 sql-server-2014 recursive-cte

我有一个存储多个行的表,每个行都声明一个点(x,y)。每行引用模式中的下一个点,因此通过链表结构递归地定义检索整个模式的查询。我开发了一个rCTE来检索看起来像这样的完整结构......

WITH list (id, next, x, y) AS ( 
  -- rCTE anchor expression
  SELECT id, next, x, y 
  FROM POINT 
  WHERE id = @id 
  UNION ALL 

  -- rCTE recursive expression
  SELECT POINT.id, POINT.next, POINT.x, POINT.y 
  FROM POINT 
  INNER JOIN list ON POINT.id = list.next) 

SELECT x, y FROM list

此外,我还有另一个表格,它引用了上述表格中存储的每种模式的起点。

最终目标是开发一个查询,该查询将返回一个二维结果,并将每个模式的所有点合并到一个以逗号分隔的列表中。这个返回值看起来像这样:

id | name | points
-----------------------
1  | test | 1,2,1,3,1,4

(点中的奇数指数是x,偶数是y。)

现在,实现这一目标的天真解决方案是循环父表,并为每个父表行设置@id并运行rCTE。这可行,我已经粗略地实现了这一点,但我不喜欢这个解决方案。是否有更好的,更多的" SQL"实现这一目标的方法是什么?

1 个答案:

答案 0 :(得分:0)

以下是我提出的解决方案,其中" AREA"是父表,它引用给定区域中的起始点。

WITH list (id, next, latitude, longitude, path) AS (  
    -- rCTE anchor expression
    SELECT POINT.id, next, latitude, longitude, path = 1
    FROM AREA INNER JOIN POINT ON AREA."start" = POINT.ID  
    UNION ALL  

    -- rCTE recursive expression
    SELECT POINT.id, POINT.next, POINT.latitude, POINT.longitude, list.path + 1
    FROM POINT INNER JOIN list ON POINT.id = list.next)  

SELECT a.name, points = STUFF(  
    (SELECT ',' + CAST(latitude AS VARCHAR) + ',' + CAST(longitude AS VARCHAR)  
        FROM list b  
        WHERE a.name = b.name  
        ORDER BY b.path ASC  
        FOR XML PATH('')),  
        1, 1, '')  
FROM list a