Graph can be represented using vertex and edge table .
Vertex holds nodes details and edge holds the relationship .
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
Graph :
I am trying to get direct neighbor of each node using SQL query .
OUTPUT
---------------------------
ID | COUNT
---------------------------
A 3
B 3
C 1
D 2
E 1
Explanation :
A has connection to E , D , B
B has connection to C, A, D
To add this variant:
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;
Please check following SQL query giving the exact result you are looking for
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;
although you have named your tables as Vertex and Edge all solutions provided here seem to be SQLScript solutions instead of a Graph language solution.
I tried to create a Graph database solution for your request, but I had a few difficulties that I had to overcome.
First, since I am new to Graph I could not find a direct solution. You know Edge's are directed records. But your question wants total number of neighbors in both directions. So I had to dublicate the rows by cross-changing the source and target columns.
Then I used following procedure
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;
But above code works only for a single vertex.
I had to create HANA database cursor and loop through all vertices then call this SP for each.
I have stored the results in a temp table and got the result you requested by querying this temp table.
I hope it helps,
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
You can use the following query:
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
to get:
Node1 Node2
-------------
A B
A B
B C
B D
B D
A D
A B
A E
This is a simplified, stripped down, version of the EDGE
table, that contains only node connection information.
You can further strip down using 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
so that duplicates are removed:
Node1 Node2
-------------
A B
A D
A E
B C
B D
You can now wrap the above query in a CTE
, unpivot and then count:
;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
Output:
Node cnt
-----------
A 3
B 3
C 1
D 2
E 1
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.