使用 CTE 显示数据中的传递关系

Using CTEs to show transitive relationships in data

我正在研究一个考古数据库,其中包含几个描述地层单元之间空间关系的 table。这很简单——一个单位要么在另一个单位之上,要么在另一个单位之下。为此,我有一个 table 记录 unit_1、unit_2 以及它们之间的空间关系类型(上方或下方)。我还想生成一个视图,该视图还记录了可​​传递的对应项。换句话说,如果单元 A 高于单元 B,我还想要一个临时行,说明单元 B 低于单元 A。

这就是我的 CTE 目前的样子。我收到的错误是 "ERROR: relation "matrix_cte" does not exist",所以这可能不是解决问题的方法。但是这里的想法是,当关系是 'above'(与 1 相同)时,INSERT 命令应该在两个单位颠倒的地方创建的 table 添加一个新行,并且关系低于(或 2)。非常感谢任何帮助,提前致谢。

WITH matrix_cte  (unit, related_unit, relationship)
AS (SELECT lookup_unit,
lookup_unit_2,
lookup_unit_relationship

FROM register_unit_matrix)
INSERT INTO matrix_cte(unit, related_unit, relationship)
SELECT lookup_unit_2, lookup_unit, 2
FROM (register_unit_matrix

INNER JOIN matrix_cte ON ((register_unit_matrix.lookup_unit = matrix_cte.unit)))
WHERE relationship = 1;

你不能 INSERT 进入 CTE。 CTE 是一个逻辑table,它是一个结果集的别名。您可以从 CTE SELECT。 不太确定您要在那里实现什么目标。

ERROR: relation "matrix_cte" does not exist

此错误消息意味着您只能 INSERT 进入关系 (tables)。 CTE 不是 table,它不是数据库中的永久对象,并且您的数据库没有名为 matrix_cte.

的 table

要生成所有关系,包括直接关系和反向关系,您可以 UNION 将两个结果集放在一起。如果你原来的table只有一个方向的关系,那么你可以使用UNION ALL,查询会更快。我的意思是,如果原始 table 对于同一对单位从来没有两行:

unit1, unit2, 1
unit2, unit1, 2

那么您可以使用下面的UNION ALL。如果原始 table 可能有这样的重复项,您应该使用 UNION 删除多余的重复项。

-- all direct relationships as they are
SELECT 
    lookup_unit,
    lookup_unit_2,
    lookup_unit_relationship
FROM register_unit_matrix

UNION

-- inverse all relationships 
SELECT 
    lookup_unit_2,
    lookup_unit,
    CASE WHEN lookup_unit_relationship = 1 THEN 2 ELSE 1 END AS lookup_unit_relationship
FROM register_unit_matrix

您可以将上述查询放入视图中,或按原样使用。