递归CTE,包括锚点内的联合和递归表达式

时间:2018-06-29 20:07:07

标签: sql sqlite common-table-expression

所以我有三个具有以下模式的表,

Users(id, name)

Colleagues(id1, id2)

Friends(id1, id2)

我需要编写一个查询,该查询返回每对id,以便可以使用同事和朋友之间的任意数量的连接从id_1到达id_2。 我计算出一个查询,该查询使我可以使用“同事”或“朋友”建立每个联系,但不能同时使用两者。 这就是我想在同一个CTE中使用两个表的想法:

WITH RECURSIVE Reachable (id_1, id_2)
AS (
SELECT
    *
FROM (
    SELECT
        id,
        FRIENDS.id2
    FROM
        USERS,
        FRIENDS
    WHERE
        FRIENDS.id1 = USERS.id
    UNION
    SELECT
        id,
        COLLEAGUES.id2
    FROM
        USERS,
        COLLEAGUES
    WHERE
        COLLEAGUES.id1 = USERS.id)
UNION
SELECT
    *
FROM (
    SELECT
        REACHABLE.id_1,
        FRIENDS.id2
    FROM
        REACHABLE,
        FRIENDS
    WHERE
        REACHABLE.id_2 = FRIENDS.id1
    UNION
    SELECT
        REACHABLE.id_1,
        COLLEAGUES.id2
    FROM
        REACHABLE,
        COLLEAGUES
    WHERE
        REACHABLE.id_2 = COLLEAGUES.id1));

但是我遇到了这个错误:

Error: near line 1: recursive reference in a subquery: Reachable

这是否意味着我通常不能/应该在递归调用中使用子查询?甚至可以在同一CTE中执行此查询?如果是这样,我该怎么办? 预先感谢!

1 个答案:

答案 0 :(得分:1)

对递归CTE的引用必须不能在子查询中,并且用UNION(ALL)分隔的两个部分必须是WITH的顶层。

如果此查询的朋友和同事之间没有区别,则只需合并两个表,然后再执行递归CTE:

WITH RECURSIVE
Connections AS (
  SELECT id_1, id_2 FROM Colleagues
  UNION ALL 
  SELECT id_1, id_2 FROM Friends
),
Reachable(id_1, id_2) AS (
  SELECT ...
  FROM Users, Connections
  ...
  UNION
  ...
)
SELECT * FROM Reachable;