2017-11-17 8 views
1

Ich versuche eine SPARQL-Abfrage zu erstellen, die die Schüler eines Lehrers findet und alle Lehrer mit alle diese Schüler findet (sie können mehr haben Studenten).Einen Satz finden, der alle Werte eines Originalsatzes in einer SPARQL-Abfrage enthält

Dies ist, was ich bisher:

SELECT ?otherTeacher 
WHERE { 
VALUES ?teacher {$teacher} 
    ?teacher hasStudent ?student . 
    ?otherTeacher hasStudent ?student . 
    FILTER(?teacher <> ?otherTeacher) 
} 

Hier sind die zu erwartenden Fälle mit den unten stehenden Daten:
- Wenn teacher1 gegeben ist, zeigt teacher3 sollte nur bis (teacher3 alle Schüler unterrichtet, die teacher1 lehrt).
- Wenn teacher2 angegeben ist, sollten sowohl teacher1 als auch teacher3 angezeigt werden (sowohl teacher1 als auch teacher3 unterrichten alle Schüler, die teacher2 unterrichtet).
- Wenn Lehrer3 angegeben ist, sollten keine Lehrer auftauchen (kein anderer Lehrer unterrichtet alle Schüler, die Lehrer3 unterrichtet).

<teacher1> <hasStudent> "Alice" . 
<teacher1> <hasStudent> "Bob" . 
<teacher1> <hasStudent> "Charlie" . 
<teacher2> <hasStudent> "Alice" . 
<teacher2> <hasStudent> "Dan" . 
<teacher3> <hasStudent> "Alice" . 
<teacher3> <hasStudent> "Bob" . 
<teacher3> <hasStudent> "Charlie" . 
<teacher3> <hasStudent> "Dan" . 

Wie füge ich eine Anforderung, dass? OtherTeacher alle Schüler hat das? Lehrer hat (dass der neue Satz enthält mindestens alle Elemente des ursprünglichen Satzes)?

+1

Bitte teilen Sie die Daten in Turtle oder N-Triples-Format. Ich möchte die Daten nicht zum Testen neu erfinden ... – AKSW

+0

@AKSW Ich habe eine Bearbeitung vorgenommen - lassen Sie mich wissen, wenn die Formatierung falsch ist. –

+0

Nun, es ist nicht gültig Turtle Format ... fehlende Präfix Deklaration, fehlende Punkte als Zeilenende. Studenten sind Stringliterale? – AKSW

Antwort

3

Wenn ein Lehrer gegeben ist, könnten Sie diese Abfrage versuchen:

SELECT DISTINCT ?otherTeacher 
WHERE { 
VALUES ?teacher {<teacher1> } 
    ?otherTeacher <hasStudent> ?student . 
    FILTER(?teacher != ?otherTeacher) 
    FILTER NOT EXISTS { 
    ?teacher <hasStudent> ?s . 
    FILTER NOT EXISTS {?otherTeacher <hasStudent> ?s .} 
    } 
} 

Es „double-Negation“ verwendet, dh es prüft, dass kein Schüler des gegebenen Lehrer gibt, die nicht von der anderen gelehrt wird Lehrer.

+0

Ich führe die Abfrage aus und ich bekomme sowohl teacher2 als auch teacher3 zurück. Der Lehrer3 hat Recht, aber Lehrer2 unterrichtet nicht alle Schüler, die Lehrer1 unterrichtet. –

+0

@AnthonyT, in GraphDB 8.3 gibt eine analoge Abfrage nur 'teacher3' zurück. –

+0

@AnthonyT Ich habe Apache Jena auf Ihren Beispieldaten verwendet und es funktioniert wie erwartet. Welchen Triple Store benutzen Sie? Die Abfrage sollte korrekt sein, wir hatten dieses Problem hier mehrmals, und Stanislav Kralin und ich posten immer die gleichen zwei Lösungen: doppelte Negation oder mehrere COUNT-Abfragen. – AKSW

1

Keine elegante Lösung, da mehrere Abfragen verschachtelt werden müssen. Es sollte einen besseren Weg geben, dieses Problem zu lösen.

Diese Lösung verwendet eine verschachtelte Abfrage, um das Maximum der Anzahl zu erhalten.
Zeile 13 soll nur Schüler für andere Lehrer einschließen, die Lehrer auch unterrichtet (um Schüler wie Dan aus der Zählung zu entfernen).

select distinct ?otherTeacher 
where{ 
    { 
    select (max(?count) as ?max) 
     where{ 
     { 
      SELECT DISTINCT ?otherTeacher (COUNT(?student) as ?count) 
      WHERE { 
      VALUES ?teacher {<teacher1> } 
      ?otherTeacher <hasStudent> ?student . 
      FILTER(?teacher != ?otherTeacher) 
      FILTER EXISTS { 
       ?teacher <hasStudent> ?student . 
      } 
      } 
      group by ?otherTeacher 
     } 
    } 
    } 
    { 
    SELECT DISTINCT ?otherTeacher (COUNT(?student) as ?count) 
    WHERE { 
    VALUES ?teacher {<teacher1> } 
     ?otherTeacher <hasStudent> ?student . 
     FILTER(?teacher != ?otherTeacher) 
     FILTER EXISTS { 
     ?teacher <hasStudent> ?student . 
     } 
    } 
    group by ?otherTeacher 
    } 
    filter(?count >= ?max) # epsilon error/no match if it's equal? 
} 
Verwandte Themen