0

I have one table (in MySQL) like this:

subject | predicate | object
A       | P1        | X
X       | P2        | B

I want to know transitive relation by using this table, so the result should like this:

element1 | predicate1 | pivot | predicate2 | element2
A        | P1         | X     | P2         | B  

I have been tried to construct the query by using nested query, but in the end i have syntax error (I think p2 (in nested query) cannot be determined in main query)

select p1.subject, p1.predicate, p1.object, p2.predicate, p2.object 
from some_relation p1 
where p1.subject = 'A' 
and p1.object = (select p2.subject from some_relation p2 where p2.object = 'B');

Anyone know how to do this kind of query? Is it possible?

Wayan Wiprayoga
  • 4,472
  • 4
  • 20
  • 30

3 Answers3

1

I would write a simple JOIN:

select p1.subject, p1.predicate, p1.object, p2.predicate, p2.object 
from some_relation p1 
inner join some_relation p2 on p1.object = p2.subject and p2.object = 'B'
where p1.subject = 'A'

Or do you mean something different?

flaschenpost
  • 2,205
  • 1
  • 14
  • 29
1

Use a self join:

SELECT 
a.subject as element1, 
a.predicate as predicate2, 
a.object as pivot, 
b.predicate as predicate2, 
b.subject as element2 FROM
table a JOIN
table b ON a.object = b.subject;
Community
  • 1
  • 1
wils484
  • 275
  • 1
  • 3
  • 14
1

You'd have to join the table with itself:

select p1.subject, p1.predicate, p1.object, p2.predicate, p2.object 
from some_relation p1 inner join some_relation p1  
  on p1.object = p2.subject
where p1.subject = 'A';

Please note that you cannot do this indefinitely. E.g., the above query only can return one "hop". If you have a transitive chain, that's hard to impossible to do in plain SQL.

Stefan Winkler
  • 3,871
  • 1
  • 18
  • 35