RDF SPARQL Query - Найти кортежи, которые не являются частью обоих условий (LEFT JOIN в SQL) - PullRequest
0 голосов
/ 21 сентября 2018

Ниже приведен набор данных, который у меня есть:

:project#1   :hasRevision        :revision#1
:revision#1  :hasRevisionNumber  1 
:project#1   :hasRevision        :revision#2
:revision#2  :hasRevisionNumber  2
:project#1   :hasRevision        :revision#3
:revision#3  :hasRevisionNumber  3
:revision#1  :committed          :A1
:A1          :hasId              1
:revision#2  :committed          :A2
:A2          :hasId              2
:revision#3  :reverted           :A1

Вариант использования:

Необходимо выбрать атрибуты, зафиксированные в каждой ревизии.
- Если пользователь запрашивает :revision#1, A1 должен быть возвращен.
- Если пользователь запрашивает :revision#2, A1 и A2 должен быть возвращен.
- Если пользователь запрашивает :revision#3, только A2 долженбудет возвращено как A1 является :reverted в :revision#3.

Ниже приведен ближайший запрос, который не работает:

select ?attribute ?id WHERE { 
    :project1  :hasRevision       ?revision . 
    ?revision  :hasRevisionNumber ?revNum ; 
               :committed         ?attribute . 
   ?attribute  :hasId             ?id . 
   FILTER NOT EXISTS { ?revision :reverted ?attribute } 
   FILTER ( ( ?revNum <= 3 && ?revNum > 0 ) && ?id in (1,2) ) 
}

Фактический результат:

A1 & A2 

Ожидаемый результат:

A2

Я понимаю проблему.Не в состоянии придумать правильный запрос.Может кто-нибудь из вас, пожалуйста, помогите.

Спасибо заранее.

Ответы [ 2 ]

0 голосов
/ 25 сентября 2018

Найден обходной путь.
Объект может быть :committed и :reverted только один раз.Поэтому используется having с агрегатной функцией для фильтрации на основе количества отношений от "revision" до "object". O Мой последний запрос приведен ниже:

prefix : <http://test.org/> 

select  ?attribute WHERE { 

        :project1  :hasRevision       ?revision . 
        ?revision  :hasRevisionNumber ?revNum ; 
                   ?s   ?attribute .
        ?attribute :hasId ?id;
        FILTER ( ( ?revNum <= 3 && ?revNum > 0 ) && ?id in (1,2) )  

}  
group by ?attribute 
having (count(?attribute) < 2 )

Вывод:

attribute
<http://test.org/A2>

Буду рад, если кто-нибудь найдет мне лучший запрос.Спасибо всем!

0 голосов
/ 21 сентября 2018

Используйте другую переменную в FILTER NOT EXISIT, например,

FILTER NOT EXISTS { ?otherRevision :reverted ?attribute } 

Редактировать: после дополнительного комментария от @Linz и добавления фильтра, чтобы искать только ревизии с меньшими номерами ревизий.

prefix : <http://base.org/>
select ?attribute ?id WHERE { 
    bind (3 as ?targetRevisionNum )
    :project1  :hasRevision       ?revision . 
    ?revision  :hasRevisionNumber ?revNum ; 
               :committed         ?attribute . 
   ?attribute  :hasId             ?id . 
    FILTER NOT EXISTS { 
        ?other :reverted ?attribute . 
        ?other :hasRevisionNumber ?otherRevNum .
        filter (?otherRevNum <= ?targetRevisionNum )
    } 
   FILTER ( ( ?revNum <= ?targetRevisionNum && ?revNum > 0 ) && ?id in (1,2) ) 
}
...