SQL 像 Table 一样查询图表

SQL Query For Graph Like Table

图可以用顶点和边表示 table .

顶点保存节点细节,边保存关系。

    VERTEX                        EDGE
    ------                       ----------------------------
     ID                           ID    |  Source   | Target
    ------                       ----------------------------
     A                            1        A            B
     B                            2        A            B
     C                            3        B            C
     D                            4        B            D
     E                            5        D            B
                                  6        A            D
                                  7        B            A
                                  8        E            A

图表:

我正在尝试使用 SQL 查询获取每个节点的直接邻居。

 OUTPUT
---------------------------
ID    | COUNT
---------------------------
 A        3
 B        3
 C        1
 D        2
 E        1

解释:

A 与 E、D、B 有关联

B 与 C、A、D 有联系

select a, count(*) as connections from
(
    select a, b from
    (
        select Source a, Target b from EDGE
        union
        select Target a, Source b from EDGE
    ) group by a,b
) group by a

您可以使用以下查询:

SELECT CASE WHEN Source < Target THEN Source ELSE Target END AS Node1,
       CASE WHEN Source >= Target THEN Source ELSE Target END AS Node2
FROM EDGE

获得:

Node1   Node2
-------------
A       B
A       B
B       C
B       D
B       D
A       D
A       B
A       E

这是 EDGE table 的简化版本,仅包含节点连接信息。

您可以使用 DISTINCT 进一步精简:

SELECT DISTINCT
       CASE WHEN Source < Target THEN Source ELSE Target END AS Node1,
       CASE WHEN Source >= Target THEN Source ELSE Target END AS Node2
FROM EDGE

以便删除重复项:

Node1   Node2
-------------
A       B
A       D
A       E
B       C
B       D

您现在可以将上述查询包装在 CTE 中,逆透视然后计数:

;WITH SimpleEDGE AS (
    SELECT DISTINCT
           CASE WHEN Source < Target THEN Source ELSE Target END AS Node1,
           CASE WHEN Source >= Target THEN Source ELSE Target END AS Node2
    FROM EDGE
)
SELECT Node, COUNT(*) AS cnt
FROM (
    SELECT Node1 AS Node
    FROM SimpleEDGE

    UNION ALL

    SELECT Node2 AS Node
    FROM SimpleEDGE
) AS t
GROUP BY Node

输出:

Node    cnt
-----------
A       3
B       3
C       1
D       2
E       1

要添加此变体:

select source, count(distinct target) 
from
    (select  source, target 
    from edge e_out
    union all
    select  target, source -- note the switch of src/trgt columns
    from edge e_in)
group by source
order by source;

请检查以下 SQL 查询,给出您正在寻找的确切结果

select
    Vertex.ID,
    Count(Neighbour) as "Count"
from GraphVertex as Vertex
left join (
select
    v.ID,
    e.Target as Neighbour
from GraphVertex as v
inner join GraphEdge as e
    on v.ID = e.Source

union

select
    v.ID,
    e.Source as Neighbour
from GraphVertex as v
inner join GraphEdge as e
    on v.ID = e.Target
) as Neighbours
    on Vertex.ID = Neighbours.ID
group by Vertex.ID
order by Vertex.ID;

尽管您已将 table 命名为 Vertex 和 Edge,但此处提供的所有解决方案似乎都是 SQLScript 解决方案而不是图形语言解决方案。

我尝试根据您的要求创建图形数据库解决方案,但我遇到了一些必须克服的困难。

首先,由于我是 Graph 的新手,我找不到直接的解决方案。你知道 Edge 是定向记录。但是您的问题需要两个方向的邻居总数。所以我不得不通过 cross-changing 源和目标列来复制这些行。

然后我使用了以下程序

CREATE PROCEDURE graphProcedureSample2(in ID varchar(2), out cnt int)
LANGUAGE GRAPH READS SQL DATA AS
BEGIN
    Graph g = Graph("A00077387", "SAMPLEGRAPHWORKSPACE");
    cnt = 0;
    Vertex v = Vertex(:g, :ID);
    Multiset<Vertex> neighbors = NEIGHBORS (:g, :v, 1, 1);
    Multiset<Edge> edges = EDGES (:g, :v, :neighbors);
    cnt = INT(COUNT(:neighbors));
END;

但以上代码仅适用于单个顶点。

我必须 create HANA database cursor 并遍历所有顶点,然后为每个顶点调用此 SP。

我已将结果存储在临时 table 中,并通过查询此临时 table 获得了您请求的结果。

希望对你有所帮助,