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 获得了您请求的结果。
希望对你有所帮助,
图可以用顶点和边表示 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 获得了您请求的结果。
希望对你有所帮助,