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

时间:2019-03-18 23:39:02

标签: sql postgresql common-table-expression

我正在研究一个考古数据库,该数据库包括几个描述地层单位之间空间关系的表格。这很简单-一个单位位于另一个单位的上方或下方。为此,我有一个表来记录unit_1,unit_2以及它们之间的空间关系类型(上方或下方)。我还想生成一个视图,该视图还记录传递对象。换句话说,如果单元A在单元B上方,则我还想要一条临时行,说明单元B在单元A之下。

这是我的CTE当前的样子。我得到的错误是“错误:关系“ matrix_cte”不存在“,所以这可能不是这样做的方法。但是这里的想法是,当关系“高于”(与1相同)时,INSERT命令应在创建的表中添加一个新行,将两个单位反转,并且关系低于(或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;

1 个答案:

答案 0 :(得分:3)

您不能INSERT进入CTE。 CTE是逻辑表,它是结果集的别名。您可以SELECT来自CTE。 不太确定要在此实现什么。

  

错误:关系“ matrix_cte”不存在

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


要生成所有关系(正向和反向),您可以UNION将两个结果集放在一起。如果原始表仅在一个方向上具有关系,则可以使用UNION ALL,查询会更快。我的意思是,如果原始表永远不会有两行用于同一对单元:

unit1, unit2, 1
unit2, unit1, 2

然后您可以在下面使用UNION ALL。如果原始表可能包含此类重复项,则应使用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

您可以将此查询放在视图中,或直接使用。