我想在sql-server-2017-graph中选择可选关系。与sparql中的optional
类似,例如:
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox
WHERE { ?x foaf:name ?name .
OPTIONAL { ?x foaf:mbox ?mbox }
}
来自https://www.w3.org/2001/sw/DataAccess/rq23/#OptionalMatching。
SELECT name, mbox
FROM Persons
LEFT JOIN PersonMailBoxLink ON Persons.$node_id = PersonMailBoxLink.$from_id
LEFT JOIN MailBoxes ON PersonMailBoxLink.$to_id = MailBoxes.$node_id
通过MATCH
有更简单的方法吗?
documentation of MATCH
描述没有“可选”构造和remarks州:
OR
模式不支持
NOT
和MATCH
个运算符。可以使用MATCH
子句中的AND
将WHERE
与其他表达式结合使用。但是,不支持将其与使用OR
或NOT
的其他表达式相结合。
答案 0 :(得分:1)
您可以将LEFT JOIN
与MATCH
合并。将可选的MATCH
放在单独的嵌套查询中。将可选子查询放在LEFT JOIN
- 子句中。
查询有点麻烦。主graph search pattern和可选的图搜索模式需要单独的Node
- 表来使用图MATCH
- 语法。 Node
表的第三个实例需要LEFT JOIN
的可选子句。第三个Node
- 表实例必须与用于Node
主查询部分的MATCH
表分开,因为使用MATCH
需要 1 table_or_view_name
<joined_table>
,不能使用SQL Graph Sample Database。
OP示例没有主图搜索模式,因此使用嵌套JOIN
几乎没有什么好处。但是,这将是生成的查询:
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];
使用主图搜索模式和可选图搜索模式的更加扩展的示例更好地演示了将图MATCH
与可选LEFT JOIN
组合在一起。以下使用sample database;选择约翰的朋友以及这些朋友喜欢的餐馆:
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
在原来的MATCH
§Arguments中,每个人都喜欢餐馆,所以上面的复杂查询与MATCH(person1-(friendOf)->person2-(likes)->Restaurant)
之间没有区别。但是,当你删除Sally喜欢Ginger和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')
使用可选LEFT JOIN
的查询仍然会将Sally作为John
的朋友返回。结果显示Sally餐厅的NULL
。 MATCH(person1-(friendOf)->person2-(likes)->Restaurant)
没有显示莎莉。
1 Use views and table valued functions as node or edge tables in match clauses和jsfiddle描述了可以在MATCH
- 子句中使用的表的这种限制。 < / p>