You can combine LEFT JOIN
with MATCH
. Put the optional MATCH
in a separate nested query. Put the optional subquery in a LEFT JOIN
-clause.
The query is a bit cumbersome. The main graph search pattern and the optional graph search pattern need separate Node
-tables to use the graph MATCH
-syntax. A third instance of the Node
-table is needed to LEFT JOIN
the optional clause on. This third Node
-table instance must be separate from the Node
-table used to MATCH
the main query part on since using MATCH
requires1 a table_or_view_name
and cannot use a <joined_table>
.
The OP example has no main graph search pattern, so there is little benefit from using a nested JOIN
. However, this would be the resulting query:
SELECT [pLhs].[name],
[mbox]
FROM [Persons] as [pLhs]
LEFT JOIN (
SELECT [pRhs].$node_id AS [pRhsNodeId],
[mbox]
FROM [Persons] as [pRhs]
[PersonMailBoxLink],
[MailBoxes]
WHERE MATCH ([Persons]-([PersonMailBoxLink])->[MailBoxes])
) AS [optionalGsp] ON [pLhs].$node_id = [optionalGsp].[pRhsNodeId];
A more extended example with both a main graph search pattern and an optional graph search pattern give a better demonstration of combing graph MATCH
with optional LEFT JOIN
. The following uses the SQL Graph Sample Database; select John's friends and optionally the restaurants that these friends like:
SELECT [Person].[Name] as friend,
[optionalGsp].[resaurantName],
FROM [Person] AS person1,
[Person] AS person2,
[friendOf],
[Person] AS person2Lhs
LEFT JOIN (
SELECT person2Rhs.$node_id AS rhsNodeId,
[Restaurant].[Name] AS restaurantName
FROM [Person] AS person2Rhs,
[likes],
[Restaurant]
WHERE MATCH (person2Rhs-(likes)->Restaurant)
) AS optionalGsp
WHERE MATCH (person1-(friendOf)->person2)
AND person1.name = 'John'
AND person2.$node_id = person2Lhs.$node_id
In the original sample database every person likes a restaurant, so the is no difference between the complicate query above and MATCH(person1-(friendOf)->person2-(likes)->Restaurant)
. However, when you delete Sally liking Ginger and Spice:
DELETE FROM likes
WHERE $from_id = (SELECT $node_id FROM Persons WHERE name = 'Sally')
AND $to_id = (SELECT $node_id FROM Restaurants WHERE name = 'Ginger and Spice')
The query with the optional LEFT JOIN
still returns Sally as a friend of John
. The results show NULL
for Sally's restaurant. MATCH(person1-(friendOf)->person2-(likes)->Restaurant)
does not show Sally.
1 MATCH
§Arguments and Use views and table valued functions as node or edge tables in match clauses describe this restriction on the tables that can be used in the MATCH
-clause.