使用 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
您可以将上述查询放入视图中,或按原样使用。
我正在研究一个考古数据库,其中包含几个描述地层单元之间空间关系的 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
.
要生成所有关系,包括直接关系和反向关系,您可以 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
您可以将上述查询放入视图中,或按原样使用。