BINDing to inlined data provided by VALUES, and braces - sparql

I tried the following query on WDQS:
SELECT ?item ?itemLabel ?string ?StringLabel ?iri ?iriLabel
WHERE {
VALUES ?item { wd:Q1339 }
BIND( STR(?item) AS ?string ).
BIND( IRI(?string) AS ?iri ).
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
And the result has ?string and ?iri value. However, if I place an extra pair of braces in the query expression
SELECT ?item ?itemLabel ?string ?StringLabel ?iri ?iriLabel
WHERE {
VALUES ?item { wd:Q1339 }
{
BIND( STR(?item) AS ?string ).
BIND( IRI(?string) AS ?iri ).
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
}
?string and ?iri in the result are empty, looking as if ?item is missing in the first BIND expression. Why is the result different?

SPARQL's "bottom-up evaluation" is often better understood by its other label, i.e., "inside-out evaluation". That is, nesting is evaluated from the innermost to the outermost.
If you flip the nesting, you'll see the results you expected --
SELECT ?item ?itemLabel ?string ?StringLabel ?iri ?iriLabel
WHERE
{
BIND( STR(?item) AS ?string ).
BIND( IRI(?string) AS ?iri ).
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
{
VALUES ?item { wd:Q1339 }
}
}

Related

How to return null results in SPARQL?

I'm using the Wikidata SPARQL Query Service with the following query:
SELECT ?item ?itemLabel ?class ?classLabel ?projectLabel WHERE {
VALUES ?item { wd:Q1 wd:Q367204 }
?item wdt:P31 ?class;
wdt:P18 ?project.
SERVICE wikibase:label { bd:serviceParam wikibase:language "en,en". } }
link to the query
When running the query there is a result for Q1 because there is an image, but there is no result for Q367204 because there isn't an image.
My question: How can I get results for both Q1 and Q367204 regardless if there is an image available or not?
wd:Q367204 is missing from the results because "there isn't an image", but also because there isn't an "instance of" statement (P31). Therefore, you can get results for both instances by wrapping both of these in an OPTIONAL block, with just ?item and ?itemLabel for Q367204, and all variables for Q1:
SELECT ?item ?itemLabel ?class ?classLabel ?projectLabel WHERE {
VALUES ?item { wd:Q1 wd:Q367204 }
OPTIONAL {
?item wdt:P31 ?class;
wdt:P18 ?project.
}
SERVICE wikibase:label { bd:serviceParam wikibase:language "en,en". }
}

Filter data with subquery in SPARQL

I'm trying to get some data from Wikidata. I've got a simple query which fetches information about universities:
SELECT ?item ?itemLabel ?site WHERE {
?item (p:P31/ps:P31/(wdt:P279*)) wd:Q38723;
wdt:P17 ?country;
wdt:P856 ?site.
SERVICE wikibase:label { bd:serviceParam wikibase:language "ru,en". }
}
And another query, which gets list of members of the CIS:
SELECT DISTINCT ?state WHERE {
?state wdt:P31/wdt:P279* wd:Q3624078;
p:P463 ?memberOfStatement.
?memberOfStatement a wikibase:BestRank;
ps:P463 wd:Q7779
MINUS { ?memberOfStatement pq:P582 ?endTime. }
MINUS { ?state wdt:P576|wdt:P582 ?end. }
}
Both work fine. But now I want to combine them to get list of universities which are located in the CIS. I try to do it like shown in the answer to this question:
SELECT ?item ?itemLabel ?site WHERE {
?item (p:P31/ps:P31/(wdt:P279*)) wd:Q38723;
wdt:P17 ?country;
wdt:P856 ?site.
FILTER(EXISTS {
SELECT DISTINCT ?state WHERE {
{
?state (wdt:P31/(wdt:P279*)) wd:Q3624078;
p:P463 ?memberOfStatement.
?memberOfStatement rdf:type wikibase:BestRank;
ps:P463 wd:Q7779.
MINUS { ?memberOfStatement pq:P582 ?endTime. }
MINUS { ?state (wdt:P576|wdt:P582) ?end. }
}
FILTER(?country = ?state)
}
})
SERVICE wikibase:label { bd:serviceParam wikibase:language "ru,en". }
}
But, for some reason, I get zero results. What am I doing wrong here?

Wikidata query for finding presidents

I was learning the wikidata query language, and wanted to find the US president's name along with grand father, great grand father and so on...
I tried this to get a father, but how to find the father's father and so on...
SELECT ?valLabel ?resLabel
WHERE {
?val wdt:P31 wd:Q5.
?val wdt:P27 wd:Q30.
?val wdt:P106 wd:Q82955.
?val wdt:P22 wd:Q11806.
OPTIONAL { ?val wdt:P22 ?res. }
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
}
Your query is looking for humans who are US citizens who are politicians and whose father is John Adams.
Instead, you want a query like this (in pseudo-SPARQL):
SELECT ?presidentLabel ?fatherLabel ?gFatherLabel ?ggFatherLabel ...
WHERE {
?president position_held president_of_the_US .
OPTIONAL{?president has_father ?father .}
OPTIONAL{?father has_father ?gFather .}
OPTIONAL{?gFather has_father ?ggFather .} ...
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
}
Notice that the optional is necessary, as there may be no information up to the great-grandfather of a president, in which case no information about the president would be returned at all.
In Wikidata, the following should work:
SELECT
?presidentLabel
?fatherLabel
?gFatherLabel
?ggFatherLabel
WHERE {
?president wdt:P39 wd:Q11696.
OPTIONAL{?president wdt:P22 ?father}
OPTIONAL{?father wdt:P22 ?gFather}
OPTIONAL{?gFather wdt:P22 ?ggFather}
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
}
However the query seems to time out when you look beyond the president's grandfather.
Bonus: If you want the presidents in chronological order, use this query:
SELECT ?ord ?presidentLabel ?fatherLabel ?gFatherLabel
WHERE {
?president wdt:P39 wd:Q11696 ;
p:P39 ?presidency .
?presidency ps:P39 wd:Q11696 ;
pq:P1545 ?ordString .
OPTIONAL{?president wdt:P22 ?father .}
OPTIONAL{?father wdt:P22 ?gFather .}
BIND(xsd:integer(?ordString) AS ?ord)
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
}
ORDER BY ?ord
Try this query
#Father - GrandFather and so on ...
SELECT ?childLabel ?fatherLabel ?grandFatherLabel ?greatGrandFather1Label ?greatGrandFather2Label
WHERE {
?child wdt:P31 wd:Q5.
?child wdt:P27 wd:Q30.
?child wdt:P106 wd:Q82955.
?child wdt:P22 wd:Q11806.
OPTIONAL { ?child wdt:P22 ?father. }
OPTIONAL { ?father wdt:P22 ?grandFather. }
OPTIONAL { ?grandFather wdt:P22 ?greatGrandFather1. }
OPTIONAL { ?greatGrandFather1 wdt:P22 ?greatGrandFather2. }
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
}
Here is a query with all fathers (and their fathers, as far back as there is data in Wikidata) of all US presidents:
SELECT ?presidentLabel ?fatherLabel
WHERE
{
?president wdt:P39 wd:Q11696;
wdt:P31 wd:Q5;
wdt:P22+ ?father .
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
Try it!

Path matching inside a VALUES clause

I'm trying to perform path matching inside a VALUES clause in sparql in order to match all instances and subclasses of both battles and sieges in wikidata. The following request repeatedly times out.
SELECT DISTINCT ?battle ?battleLabel WHERE {
{
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
VALUES ?type {wd:Q178561 wd:Q188055} ?battle (wdt:P31/wdt:P279*) ?type .
?battle rdfs:label ?queryByTitle.
FILTER(REGEX(?queryByTitle, "saratoga", "i"))
}
}
It seems that VALUES, esp. in conjunction with /, confuses the Blazegraph's query optimizer in that case.
Use UNION instead of VALUES:
SELECT DISTINCT ?battle ?battleLabel WHERE {
{ ?battle wdt:P31/wdt:P279* wd:Q178561 }
UNION
{ ?battle wdt:P31/wdt:P279* wd:Q188055 }
?battle rdfs:label ?queryByTitle.
FILTER(REGEX(?queryByTitle, "saratoga", "i"))
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" }
}
Alternatively, disable the optimizer and specify explicit order:
SELECT DISTINCT ?battle ?battleLabel WHERE {
hint:Query hint:optimizer "None" .
VALUES ?type {wd:Q178561 wd:Q188055}
?subtype wdt:P279* ?type .
?battle wdt:P31 ?subtype .
?battle rdfs:label ?queryByTitle.
FILTER(REGEX(?queryByTitle, "saratoga", "i"))
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" }
}

Find which direct property applied in a SPARQL query

I have a list of properties I want to apply to a specific entity mathematics: wd:Q395. In this case:
instanceOf: 'wdt:P31'
subclassOf: 'wdt:P279'
The results are:
Mathematics is instance of academic discipline and
Mathematics is subclass of exact science and formal science
Instead of making two different queries I would like to make them all at once:
SELECT ?field ?fieldLabel ?propertyApplied
WHERE {
wd:Q395 wdt:P31 | wdt:P279 ?field.
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
BIND("" AS ?propertyApplied)
}
How can I know which property applied to fill the right column? ( for example next to academic discipline I would like that it appears instance of)
I tried this but it looks weird and the results repeat themselves.
SELECT ?instanceOf ?subclassOf ?instanceOfLabel ?subclassOfLabel
WHERE {
OPTIONAL { wd:Q395 wdt:P31 ?instanceOf. }
OPTIONAL { wd:Q395 wdt:P279 ?subclassOf. }
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
}
Use VALUES or UNION:
SELECT ?field ?fieldLabel ?propertyLabel WHERE {
VALUES (?predicate) {(wdt:P31) (wdt:P279)}
wd:Q395 ?predicate ?field .
?property wikibase:directClaim ?predicate .
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
Try it!
SELECT ?field ?fieldLabel ?propertyLabel {
{ wd:Q395 wdt:P31 ?field . BIND (wd:P31 AS ?property) }
UNION
{ wd:Q395 wdt:P279 ?field . BIND (wd:P279 AS ?property) }
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
Try it!