SQL Postgres显示边的详细信息

问题描述

我有一个节点表

Table Node
Column| type
------|---------------
id    | int
x     | int
y     | int
z     | text

例如,

id | x | y | z
---|---|---|---
 0 | 0 | 0 |'a'
 1 | 0 | 1 |'b'
 2 | 1 | 0 |'c'
 3 | 1 | 1 |'d'

Table Edge
Column| type
------|---------------
source| int references Node.id
target| int references Node.id

例如,

source | target
-------|-------
   0   |   1 
   1   |   3
   3   |   2

假设节点本身没有优势,并且每个来源都是唯一的

我想显示整个边缘信息的结果

source.x | source.y | target.x | target.y
---------|----------|----------|---------
    0    |    0     |    0     |    1
    0    |    1     |    1     |    1
    1    |    1     |    1     |    0

我尝试了很多联接(节点的自我联接与带有边的内部联接),(边缘的左联接与节点的自我联接的结果)

如何获得选择结果?

解决方法

我认为您想要两个联接:

select ns.x,ns.y,nt.x,nt.y
from edge e join
     nodes n1
     on e.source = ns.id join
     nodes nd
     on e.target = nt.id
,

对于PostgreSQL,可以使用RECURSIVE WITH子句。

a)建立路径:

CREATE LOCAL TEMPORARY TABLE
node(id,x,y,z) AS (
          SELECT 0,'a'
UNION ALL SELECT 1,1,'b'
UNION ALL SELECT 2,'c'
UNION ALL SELECT 3,'d'
)
;
CREATE LOCAL TEMPORARY TABLE
edge(source,target) AS (
          SELECT 0,1
UNION ALL SELECT 1,3
UNION ALL SELECT 3,2
)
;
WITH RECURSIVE backbone AS (
  SELECT
    source::CHAR(1)||','||target::CHAR(1) AS path,1 AS hops,*
  FROM edge 
  UNION ALL SELECT
    p.path||','||c.target::CHAR(1) AS path,p.hops + 1 AS hops,c.*
  FROM backbone p JOIN edge c ON c.source=p.target
)
SELECT * FROM backbone;
  path   | hops | source | target 
---------+------+--------+--------
 0,1     |    1 |      0 |      1
 1,3     |    1 |      1 |      3
 3,2     |    1 |      3 |      2
 0,3   |    2 |      1 |      3
 1,3,2   |    2 |      3 |      2
 0,2 |    3 |      3 |      2

b)对于具有2跳和3跳的路径,请从路径中获取第一个和最后一个节点ID:

-- as above,but instead of the last line: "SELECT * FROM backbone" ...,origin_and_dest AS (
  SELECT 
    *,SPLIT_PART(path,',1       )::INT  AS origin,hops + 1)::INT  AS destination
  FROM backbone
  WHERE hops >=2
)
SELECT * FROM origin_and_dest;
  path   | hops | source | target | origin | destination 
---------+------+--------+--------+--------+-------------
 0,3   |    2 |      1 |      3 | 0      | 3
 1,2   |    2 |      3 |      2 | 1      | 2
 0,2 |    3 |      3 |      2 | 0      | 2

在路径中没有最终源ID和最终目标ID的情况下,请重新加入节点:

-- same as above,but instead of the last line: "SELECT * FROM origin_and_dest" ...
SELECT
  origin.x AS source_x,origin.y AS source_y,dest.x   AS target_y,dest.y   AS target_y
FROM origin_and_dest
JOIN node AS origin ON origin=origin.id
JOIN node AS dest   ON destination=dest.id
;
 source_x | source_y | target_y | target_y 
----------+----------+----------+----------
        0 |        0 |        1 |        0
        0 |        0 |        1 |        1
        0 |        1 |        1 |        0

您的结果并不完全,但是我真的不知道您所说的“整个边缘信息”是什么意思……您能更精确吗?

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...