SPARQL SubQuery in Filter - sparql

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" }

Related

How to filter for a condition with two columns?

For a course I follow I have to write several SPARQL queries about Lego sets. I am interested in finding out if there is a Lego theme which has a single package type.
I have the following SPARQL query:
select distinct ?theme ?package_type (count(?theme) as ?amount_of_lego_sets)
where{
?Lego_set rdf:type wd:Q58780257 .
?Lego_set sch:audienceType ?audience .
?Lego_set ex:has_package_information ?package_info .
?audience ex:belongs_to_theme ?theme .
?package_info ex:has_packaging_type ?package_type .
} group by ?theme ?package_type
order by ?theme
Which produces the following output:
As you can see there is one set that has the theme “4 Juniors” and the package type “Polybag”. Now, I am interested in themes like Advanced models or Action Wheelers which only have a single package type. However, I found it challenging to filter for these themes.
What modification to my query could I implement to remove themes which have sets that have more than one package type?
This is an interesting question. I would use FILTER NOT EXISTS to add an atom to the query body, where we make sure that the theme doesn't have two types of packages, like this:
FILTER NOT EXISTS {
?Lego_set2 sch:audienceType ?audience2 .
?Lego_set2 ex:has_package_information ?package_info2 .
#Notice that the 'theme' variable must be the same as the outer query
?audience2 ex:belongs_to_theme ?theme .
?package_info2 ex:has_packaging_type ?package_type1, ?package_type2
FILTER(?pakage_type1 != ?package_type2)}
Thus your full query should be something like:
select distinct ?theme ?package_type (count(?theme) as ?amount_of_lego_sets)
where{
?Lego_set rdf:type wd:Q58780257 .
?Lego_set sch:audienceType ?audience .
?Lego_set ex:has_package_information ?package_info .
?audience ex:belongs_to_theme ?theme .
?package_info ex:has_packaging_type ?package_type .
FILTER NOT EXISTS {
?Lego_set2 sch:audienceType ?audience2 .
?Lego_set2 ex:has_package_information ?package_info2 .
#Notice that the 'theme' variable must be the same as the outer query
?audience2 ex:belongs_to_theme ?theme .
?package_info2 ex:has_packaging_type ?package_type1, ?package_type2
FILTER(?pakage_type1 != ?package_type2)}
} group by ?theme ?package_type
order by ?theme
You could also use the aggregation approach mentioned in the comments, but hopefully this one solves your problem.

SPARQL Restrict Number of Results for Specific Variable

Suppose I want to look for some first degree neighbors of Berlin. I ask the following query:
select ?s ?p where {
?s ?p dbr:Berlin.
}
Is it possible to put a restriction on the return result, such that there are at most 5 results for each unique value of ?p?
My attempts with subqueries all time out...
But, as potentially useful if not exactly perfect solution, maybe GROUP_CONCAT, MAX/MIN or SAMPLE are of use?
SELECT
?writer (GROUP_CONCAT(?namestring; SEPARATOR = " ") AS ?namestrings)
(MIN(?namestring) AS ?min_name)
(MAX(?namestring) AS ?max_name)
(SAMPLE(?namestring) AS ?random_name)
(SAMPLE(?namestring) AS ?another_random_name_that_may_unfortunately_be_the_same_again)
WHERE {
?writer wdt:P31 wd:Q5;
wdt:P166 wd:Q37922;
wdt:P735 ?firstname.
?firstname wdt:P1705 ?namestring.
}
GROUP BY ?writer
HAVING ((COUNT(?writer)) > 2 )
LIMIT 20
See it live here.
And, as you can see, SAMPLE is apparently evaluated only once, so using it repeatedly does not get you closer to five (different) samples.
(You can leave out the HAVING for your use. I only included it to restrict it to useful examples))

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 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