SPARQL - Extract Label from entity URI - sql

I'm trying to extract a list of diseases that have symptoms from Wikidata.
The thing is, when I query I get a list of entity URIs, not a list of labels, for the Symptoms column.
My query, tested on here :
SELECT ?disease ?diseaseLabel (GROUP_CONCAT(?symptoms; SEPARATOR = ", ") AS ?Symptoms)
WHERE {
?disease wdt:P31 wd:Q12136.
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
OPTIONAL { ?disease wdt:P780 ?symptoms. }
FILTER(EXISTS { ?disease wdt:P780+ ?symptom. })
}
GROUP BY ?disease ?diseaseLabel
Which gives the following result :
For example , at the disease measles ,what I want to select for the Symptoms column is : fever, cough, runny nose, maculopapular rash, lymphadenopathy, anorexia, diarrhea..
Which are the exact labels for the URIs in the Symptom column for the particular disease.
Any help/hint and suggestions are welcomed , thank you !

Related

SPARQL Distance problem WIKIDATA - problem with distance measuring

I am doing SPARQL exercise right now - I want to find all places that dont have airport in 100km range.
Right now I am stuck, cause I wanted to union them to filter data, but that isnt working.
Please help me to understand how to connect data to be able to filter the distance :)
To simplify code I changed all the cities to only Berlin.
SELECT ?placeCoor WHERE{
{
SELECT ?placeCoor WHERE{
?place wdt:P31/wdt:P279* wd:Q1248784.
?place wdt:P625 ?placeCoor.
}
}
UNION
{
SELECT DISTINCT ?berlinLoc WHERE {
wd:Q64 wdt:P625 ?berlinLoc .
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". } }
}
FILTER (geof:distance(?placeCoor, ?berlinLoc) >5 )
}

How to filter a variable by a property included in the variable in SPARQL?

I want to write a SPARQL query that would return the first name of a person based on the ranking of the name on Wikidata.
For example, let's say I want the second first name of Mozart (Chrysostom).
This is what I have so far (Mozart Wikidata ID is Q254, first name's property is P735, with P1545 giving the ordinal position of the name):
SELECT DISTINCT ?full_name ?full_nameLabel ?first_nameLabel ?rank
WHERE
{
VALUES ?full_name {wd:Q254} .
?full_name p:P735 [pq:P1545 ?rank] ;
p:P735 [ps:P735 ?first_name] ;
FILTER regex(?rank, "2")
SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }
}
However here the filter only applies to the rank variable, and not on the first_name variable:
Query result:
I think that the problem comes from the fact that the rank property is a sub-element of the first_name property. Would you know of a way to filter the first_name variable by the rank variable?
SELECT DISTINCT ?id ?idLabel ?first_nameLabel ?rank
WHERE {
VALUES ?id {wd:Q254} .
?id p:P735 [
pq:P1545 ?rank;
ps:P735 ?first_name
]
FILTER(?rank = "2")
SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }
}

SPARQL - Concat values on multiple rows

I want a list of all currencies by El Salvador with their subdivision.
I use this query:
SELECT ?currency ?currencyLabel ?currencyIso4217 ?subdivisionLabel {
?currency wdt:P498 ?currencyIso4217 .
?currency wdt:P9059 ?subdivision .
SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }
{
?country wdt:P38 ?currency .
BIND(wd:Q792 AS ?country).
SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }
}
}
Try it here: Link
This gives the following result:
Works perfectly. But row 2 and three are the same currency. That currency only uses multiple names for the subdivision. I want them to concat so I get this output:
Is that possible?
Grouping in SPARQL works similar to SQL.
The function GROUP BY combines results that have identical values into groups. Afterwards, an aggregate function is applied to the other (non-identical) values for each group.
Typical aggregate functions are COUNT, SUM, MIN, MAX, AVG, GROUP_CONCAT, and SAMPLE.
For you GROUP_CONCAT is of interest. It performs a string concatenation across the values of a group. With the argument separator you can even specify a separator character. The order of the strings is arbitrary.
The syntax of GROUP BY and GROUP_CONCAT was already given to you in the comment by UninformedUser but I repeat it here in a slightly adapted form:
SELECT ?currency ?currencyLabel ?currencyIso4217 (GROUP_CONCAT(?subdivisionLabel; separator = ", ") as ?subdivisionLabels) {
BIND(wd:Q792 AS ?country).
?country wdt:P38 ?currency .
?currency wdt:P498 ?currencyIso4217 .
?currency wdt:P9059 ?subdivision .
?subdivision rdfs:label ?subdivisionLabel .
FILTER(lang(?subdivisionLabel) = 'en')
SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }
} GROUP BY ?currency ?currencyLabel ?currencyIso4217

How to follow a path depend on qualifier SPARQL

I like to query out all people who is connected to each other but filter by qualifier value of the path
For example, the query below will get all human related to Putin. But his spouse, whose in statement get the qualifier "endtime" should not be followed
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?pep ?pepLabel ?relation ?relationLabel ?relatedPerson ?relatedPersonLabel ?endtimequalifier
WHERE
{
VALUES ?pep {wd:Q7747}
?relatedPerson wdt:P31 wd:Q5.
?pep ?relation ?relatedPerson.
#What should I put here for the query to ignore the spouse since the endtimequalifier is available
OPTIONAL{
?pep p:P26 [ps:P26 ?spouse; pq:P582 ?endtimequalifier ].
}
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
}

SPARQL question: how to return property labels and associated date qualifiers from Wikidata

I am trying to return results for a set of persons (Edinburgh University alumni) who have held political office. I would like to return the title label of the office held, along with the start and end dates for each office, with many individuals holding multiple positions. I seem to be able to get one or the other or can get it to work if the person only held one position, but can't get the two to come together where multiple offices were held.
My current version of the query is below. This will give me the start and end dates, but rather than the label if the political office, such as Member of the [x] Parliament of the United Kingdom, ?officeLabel returns a value such as: statement/Q4668868-E3734C7D-40F0-4D4A-8208-E3D6B8C944CB
SELECT DISTINCT ?alumni ?fullName ?roleLabel ?officeLabel ?start ?end WHERE {
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
?alumni wdt:P69 wd:Q160302.
?alumni rdfs:label ?fullName.
?alumni wdt:P106 ?role.
#Use Values to separate out politicians - Q82955
VALUES (?role) {
(wd:Q82955)
}
#Select only where position of office is stated but make dates optional
?alumni p:P39 ?office.
OPTIONAL { ?office pq:P580 ?start. }
OPTIONAL { ?office pq:P582 ?end. }
FILTER(LANGMATCHES(LANG(?fullName), "en"))
FILTER(NOT EXISTS { FILTER(LANGMATCHES(LANG(?fullName), "en-ca")) })
FILTER(NOT EXISTS { FILTER(LANGMATCHES(LANG(?fullName), "en-gb")) })
}
ORDER BY ?fullName
LIMIT 10
Yeah, I still get tripped up on qualifiers and the Wikidata Data Model too.
Diagram by
By Michael F. Schönitzer - Own work, based on File:Rdf mapping.svg, CC
BY 4.0, https://commons.wikimedia.org/w/index.php?curid=63880194
After going the "p: route" from the "item", you need the "ps: route" to get back to the "simple value".
So, using this to slightly modify your query gives the results I think you want.
SELECT DISTINCT ?alumni ?fullName ?roleLabel ?officeLabel ?start ?end WHERE {
?alumni wdt:P69 wd:Q160302.
?alumni rdfs:label ?fullName.
?alumni wdt:P106 ?role.
VALUES (?role) {
(wd:Q82955)
}
?alumni p:P39 ?officeStmnt.
?officeStmnt ps:P39 ?office.
OPTIONAL { ?officeStmnt pq:P580 ?start. }
OPTIONAL { ?officeStmnt pq:P582 ?end. }
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
FILTER(LANGMATCHES(LANG(?fullName), "en"))
FILTER(NOT EXISTS { FILTER(LANGMATCHES(LANG(?fullName), "en-ca")) })
FILTER(NOT EXISTS { FILTER(LANGMATCHES(LANG(?fullName), "en-gb")) })
}
ORDER BY ?fullName
LIMIT 10
Link to query on Wikidata