Синтаксис для запроса дополнительных отношений в базе данных Microsoft SQL Server 2017 Graph?

Я хочу выбрать дополнительные отношения в sql-server-2017-graph. Аналогично optional в sparql, например:

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.

Аналогично LEFT JOIN в обычном sql ; например.:

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?

документация MATCH не описывает "необязательную" конструкцию и remarks состояние:

Операторы OR и NOT не поддерживаются в шаблоне MATCH. MATCH можно комбинировать с другими выражениями, используя AND в предложении WHERE. Однако объединение его с другими выражениями с использованием OR или NOT не поддерживается.


person Kasper van den Berg    schedule 11.08.2017    source источник


Ответы (1)


Вы можете комбинировать LEFT JOIN с MATCH. Поместите необязательный MATCH в отдельном вложенном запросе. Поместите необязательный подзапрос в LEFT JOIN-предложение.

Запрос немного громоздкий. Основной шаблон поиска графа и необязательный шаблон поиска графа требуют отдельного Node-таблицы для использования MATCH-синтаксиса графа. Третий экземпляр Node-таблицы необходим для LEFT JOIN включения необязательного предложения. Этот третий экземпляр Node-таблицы должен быть отделен от Node-таблицы, используемой для MATCH основной части запроса, поскольку для использования MATCH требуется1 table_or_view_name и не может использовать a <joined_table>.

В примере 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. В следующем примере используется Пример базы данных SQL Graph; выберите друзей Джона и, при желании, рестораны, которые нравятся этим друзьям:

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(person1-(friendOf)->person2-(likes)->Restaurant). Однако, когда вы удаляете Салли, которая любит имбирь и специи:

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 по-прежнему возвращает Салли как друга John. Результаты показывают NULL для ресторана Салли. MATCH(person1-(friendOf)->person2-(likes)->Restaurant) не показывает Салли.


1 MATCH §Arguments и Используйте представления и табличные значения функции в качестве узловых или пограничных таблиц в предложениях соответствия описывают это ограничение на таблицы, которые можно использовать в предложении MATCH.

person Kasper van den Berg    schedule 24.08.2017