Find all subjects that match X but don't match Y - sparql

I have a simple "Registrations" table that contain students registered for courses. A student can be registered for multiple courses.
I want to find all students registered for course 1234 that were not registered for course 5678.
So I tried this attempt:
SELECT ?student_id
WHERE {
?registration :R-Student_id ?student_id ;
:R-Course_code ?course_code .
FILTER(?course_code = "1234") .
FILTER NOT EXISTS {
?registration :R-Course_code "5678" .
}
}
ORDER BY ?student_id
But it seems like the last FILTER NOT EXISTS makes no difference to the query? I can still find student_ids from the query result that are also registered for the second course :/
What am I doing wrong here?

So I managed to solve it using some sort of "self join":
SELECT ?student_id
WHERE {
?r1 :R-Student_id ?student_id ;
:R-Course_code "1234" .
FILTER NOT EXISTS {
?r2 :R-Student_id ?student_id ;
:R-Course_code "5678" .
}
}
ORDER BY ?student_id

Related

SPARQL SubQuery in Filter

SELECT ?Name FROM <http://.../biblio.rdf>
WHERE { ?Aut name ?Name . ?Pub author ?Aut . ?Pub conf ?Conf
FILTER (?Conf IN ( SELECT ?ConfX FROM <http://.../biblio.rdf>
WHERE { ?ConfX series "ISWC" }))}
I have taken the query from http://www.renzoangles.net/files/amw2011.pdf.
Getting the malformed query syntax error when I tried the above format in AWS Neptune.
Please help me fix the above query.
If you want to test that a triple is in the data, which seems to be the intention of the exampel of "FILTER IN SELECT " here, yuo can use FILTER EXISTS
FILTER EXISTS { ?Conf series "ISWC" }

Aggregate functions in Sparql query with empty records

I've been trying to run a sparql query against https://landregistry.data.gov.uk/app/qonsole# to yield some sold properties result.
The query is the following:
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX ukhpi: <http://landregistry.data.gov.uk/def/ukhpi/>
SELECT sum(?ukhpi_salesVolume)
WHERE
{ { SELECT ?ukhpi_refMonth ?item
WHERE
{ ?item ukhpi:refRegion <http://landregistry.data.gov.uk/id/region/haringey> ;
ukhpi:refMonth ?ukhpi_refMonth
FILTER ( ?ukhpi_refMonth >= "2019-03"^^xsd:gYearMonth )
FILTER ( ?ukhpi_refMonth < "2020-03"^^xsd:gYearMonth )
}
}
OPTIONAL
{ ?item ukhpi:salesVolume ?ukhpi_salesVolume }
}
The problem is, the result from this is empty. However, if i run the same query without the SUM on the 4th line, i can see there are 11 integer records.
My thoughts are that there is a 12th, empty record which causes all the issues in the SUM operation, but sparql is not my storngest side so i'm not sure how to filter this (and remove any empty records) if that's really the problem.
I've also noticed that most of the aggregate functions do not work as well(min, max, avg). *Count does, and returns 11
I actually solved this myself, all that was needed was a coalesce which apparently existed in sparql too.
So:
SELECT sum(COALESCE(?ukhpi_salesVolume, 0))
instead of just
SELECT sum(?ukhpi_salesVolume)

SPARQL optional not bound VS filter not exists

Is there a difference (in term of performances, respects of standards or anything else) between:
select distinct ?planeWithoutPassengers where {
?planeWithoutPassengers a <http://example.org/plane> .
filter not exists {
?planeWithoutPassengers <http://example.org/hasPassenger> ?passenger .
}
}
And:
select distinct ?planeWithoutPassengers where {
?planeWithoutPassengers a <http://example.org/plane> .
optional {
?planeWithoutPassengers <http://example.org/hasPassenger> ?passenger .
}
filter (!bound(?passenger)).
}
There is no real difference. The second one is the older version which also works on SPARQL 1.0 engines. However the first one is preferred as it reads more intuitively.

SPARQL subquery wtih xsd:dateTime

I've made one query which returns the date of the Hiroshima bombing.
SELECT ?date
WHERE {
history:the_bombing_of_hiroshima history:hasStartDate ?date .
}
Result: 1945-08-06T:00:00:00
And another query which returns all of the administration that ruled the Soviet Union.
SELECT ?administration
WHERE {
?administration history:rulesCountry "The Soviet Union"^^xsd:string .
}
Now, I'm wondering. An administration in our ontology has a "startDate" and "endDate" data property. Both containing xsd:dateTime values. I want to pass the date, received from the first query into the second query so that we can get the administration that ruled the Soviet Union during the bombing of Hiroshima.
I've tried to read some SPARQL subquery examples but none of them concern dateTime filtering (check to see if a date falls between two others) and many of them are a bit confusing to me.
I suspect the query must be something like
SELECT ?administration
WHERE {
?administration history:rulesCountry "The Soviet Union"^^xsd:string .
?administration history:hasStartDate > [RESULT FROM QUERY1 HERE] && history:hasEndDate < [RESULT FROM QUERY1 HERE]
}
I'd be very grateful for any answers or pointers towards resources and tutorials I can read to get this query to work.

Group By not working in DBPedia

I am working in DBPedia. I am having a problem when using group by in Sparql.
I have this code:
SELECT ?res ?titulo
WHERE {
?res rdf:type <http://dbpedia.org/class/yago/JaguaresDeChiapasFootballers> .
?res rdfs:label ?titulo .
}
GROUP BY (?res)
LIMIT 15
I want to return a list of all in this type. But I only want to return one for each URI, I put the group by and it doesn’t work and I really don’t know why?
Can someone help me?
Your original query isn't legal SPARQL. If you paste it into the SPARQL query validator at sparql.org, you'll get the following message:
Non-group key variable in SELECT: ?titulo
If you group by ?res, then you can't select the non-group variable ?titulo. If you just want one ?titulo value per ?res, then you can use …
select ?res (sample(?titulo) as ?title)
…
SPARQL results
If you want a list of the titles, then you can use group_concat to concatenate the titles:
select ?res (group_concat(?titulo;separator=', ') as ?title)
…
SPARQL results