Wikidata SPARQL query: how to get values of the property 'applies to part' (P518) - sparql

on the page describing Hurricane Ian on wikidata Ian wikidata, we can consult which parts of countries were concerned by the event (Florida, Georgia, etc.)
I'm trying to write a query to get these information via a python script:
SELECT distinct ?label ?item ?superTypeLabel ?date ?start_date ?end_date ?countryLabel ?countryPart
WHERE { ?item wdt:P31 wd:Q63100601;
wdt:P31 ?superType;
rdfs:label ?label.
?superType rdfs:label ?superTypeLabel.
# with a point in time or start date
FILTER langMatches(lang(?label),'en').
FILTER langMatches(lang(?superTypeLabel),'en').
# with a point in time or start date
OPTIONAL { ?item wdt:P585 ?date. }
OPTIONAL { ?item wdt:P580 ?date. }
OPTIONAL { ?item wdt:P580 ?start_date. }
OPTIONAL { ?item wdt:P582 ?end_date. }
OPTIONAL { ?item wdt:P17 ?country.
?country rdfs:label ?countryLabel.
FILTER langMatches(lang(?countryLabel),'en').}
OPTIONAL { ?item wdt:P518 ?countryPart. }
# but at least one of those
FILTER(BOUND(?date) && DATATYPE(?date) = xsd:dateTime).
# not in the future, and not more than 31 days ago
BIND(NOW() - ?date AS ?distance).
FILTER(0 <= ?distance && ?distance < 365).
FILTER contains(?label,"Hurricane Ian")
}
the previous query works well, except for the ?countryPart values, the query doesn't return any value while on the HTML page the information is well represented. any help please?

I found how to get country parts by adding the following line :
OPTIONAL { ?item p:P17 [ps:P17 ?country; pq:P518 ?countryPart] }
the final query:
SELECT distinct ?label ?item ?superTypeLabel ?date ?start_date ?end_date ?country ?countryPart
WHERE { ?item wdt:P31 wd:Q63100601;
wdt:P31 ?superType;
rdfs:label ?label.
?superType rdfs:label ?superTypeLabel.
# with a point in time or start date
FILTER langMatches(lang(?label),'en').
FILTER langMatches(lang(?superTypeLabel),'en').
# with a point in time or start date
OPTIONAL { ?item wdt:P585 ?date. }
OPTIONAL { ?item wdt:P580 ?date. }
OPTIONAL { ?item wdt:P580 ?start_date. }
OPTIONAL { ?item wdt:P582 ?end_date. }
OPTIONAL { ?item p:P17 [ps:P17 ?country; pq:P518 ?countryPart] }
# but at least one of those
FILTER(BOUND(?date) && DATATYPE(?date) = xsd:dateTime).
# not in the future, and not more than 31 days ago
BIND(NOW() - ?date AS ?distance).
FILTER(0 <= ?distance && ?distance < 365).
FILTER contains(?label,"Hurricane Ian")
}

Related

Wikidata do not return me itemLabel sometimes

I am looking for people of french nationality born in 1900 (and still living). I do not well understand the behaviour of wikidata in response to my following request:
SELECT ?item ?itemLabel ?itemDescription
WHERE {
?item wdt:P31 wd:Q5.
?item wdt:P569 ?dateOfBirth.
?item wdt:P27 wd:Q142.
FILTER NOT EXISTS {?item wdt:P570|wdt:P509|wdt:P20 ?o}
FILTER("1900-00-00"^^xsd:dateTime <= ?dateOfBirth && ?dateOfBirth < "1901-00-00"^^xsd:dateTime)
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],fr". }
}
I do not understand why the folowing request do not return itemLabel for some rows; for example the itemlabel returned for https://www.wikidata.org/wiki/Q47508624 is its "id": Q47508624
By using the wikibase:language option, you're asking for Wikidata to provide you with the labels for each ?item in the ?itemLabel variable. You've requested that it provide you labels in either the language preferred by your browser ([AUTO_LANGUAGE]) or French (fr). I would guess that your browser's default language is French also. With a browser set with English as the default, I get "Hugues Esquerre" as the ?itemLabel value for wd:Q47508624 (this record has labels defined in English and Spanish).
You can add additional acceptable languages in the comma-separated list in the query to increase the liklihood of getting label values back:
SELECT ?item ?itemLabel ?itemDescription
WHERE {
?item wdt:P31 wd:Q5.
?item wdt:P569 ?dateOfBirth.
?item wdt:P27 wd:Q142.
FILTER NOT EXISTS {?item wdt:P570|wdt:P509|wdt:P20 ?o}
FILTER("1900-00-00"^^xsd:dateTime <= ?dateOfBirth && ?dateOfBirth < "1901-00-00"^^xsd:dateTime)
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],fr,en,es". }
}

Wikidata query for items with one Wikipedia page not in English

I want to find Wikidata items, with each referring to exactly one Wikipedia page which is not an en. Wikipedia page.
I came up with this query:
SELECT ?item WHERE {
?article schema:about ?item .
FILTER (SUBSTR(str(?article), 9, 2) != "en") .
{
SELECT ?item (COUNT(DISTINCT ?lang) AS ?count) WHERE {
?item wdt:P1367 ?yp_id . # BBC 'Your paintings' artist identifier
?article schema:about ?item .
FILTER (SUBSTR(str(?article), 11, 15) = ".wikipedia.org/") .
?article schema:inLanguage ?lang .
} GROUP BY ?item
HAVING (?count=1)
ORDER BY DESC (?count)
}
}
It executes. However, I always get a timeout.
Is there a better query to achieve what I am looking for?
Here's some tip:
Since you take only ?count=1, there is no reason to order by ?count.
Since for each article you can have only one ?lang, you can count by ?article without considering a redundant variable.
Instead of working on (sub)strings, just use the schema:isPartOf property for selecting the specific domain that you want to exclude.
Use FILTER NOT EXISTS instead of FILTER (... != ...)
The fourth optimiziation is the most important and it is sufficient per se.
SELECT ?item WHERE {
FILTER NOT EXISTS {
?article schema:about ?item ;
schema:isPartOf <https://en.wikipedia.org/> .
}
{
SELECT ?item (COUNT(DISTINCT ?article) AS ?count) WHERE {
?item wdt:P1367 ?yp_id . # BBC 'Your paintings' artist identifier
?article schema:about ?item .
FILTER (SUBSTR(str(?article), 11, 15) = ".wikipedia.org/") .
}
GROUP BY ?item
HAVING (?count=1)
}
}

SPARQL query that returns Wikidpedia labels from Wikidata itemLabel

I am new to SPARQL,
Is it possible to write a query that returns Wikipedia box information for a corresponding item label from the Wikipedia box for the Arabic Language that appears at the bottom of the Wikidata item page?
see the picture:
Instead of the Wikipedia URL in the following Query, I need to return the Wikipedia Label, in our case (الرامة (جنين))
Try Query on Wikidata Query Service
SELECT DISTINCT ?article ?item ?itemLabel ?itemDescription ?entity_type ?main_category (GROUP_CONCAT(DISTINCT(?altLabel); separator = ", ") AS ?altLabel_list) WHERE {
?item ?label "الرامة"#ar.
?item wdt:P31 ?entity_type .
MINUS { ?item wdt:P31 wd:Q4167410}
OPTIONAL{ ?item wdt:P910 ?main_category}
?article schema:about ?item;
schema:isPartOf <https://ar.wikipedia.org/>;
OPTIONAL { ?item skos:altLabel ?altLabel . FILTER (lang(?altLabel) = "ar") }
SERVICE wikibase:label { bd:serviceParam wikibase:language "ar" .}
}
GROUP BY ?article ?item ?itemLabel ?itemDescription ?entity_type ?main_category
This is the answer by the UninformedUser
> SELECT ?article ?wikipediaLabel WHERE
> { ?article schema:about wd:Q12187640 . ?article schema:isPartOf <https://ar.wikipedia.org/>; schema:name
> ?wikipediaLabel }

Return cities in Wikidata SPARQL Query, similar to a Wikipedia page

I'm not sure what I'm doing wrong. I have a nice list, but not only are the cities duplicating, but I'm unsure how they're defined as cities. I would expect to see London in the results and have similar results to this Wikipedia page. These results are quite different to the Wikipedia page.
I want to:
Get a list of cities, with their first-level administrative country subdivision (province/state/region), similar to this Wikipedia page
While avoiding duplicate cities.
SELECT ?city ?cityLabel ?country ?population ?countryLabel ?region ?regionLabel ?lat ?long
WHERE
{
?city wdt:P31/wdt:P279 wd:Q515 . # find instances of subclasses of city
?city (wdt:P131) ?region.
?region wdt:P31/wdt:P279 wd:Q10864048 .
?city wdt:P1082 ?population .
?city wdt:P17 ?country . # Also find the country of the city
?city p:P625 ?statement . # coordinate-location statement
?statement psv:P625 ?coordinate_node .
OPTIONAL { ?coordinate_node wikibase:geoLatitude ?lat. }
OPTIONAL { ?coordinate_node wikibase:geoLongitude ?long.}
FILTER (?population > 100000) .
# choose language
SERVICE wikibase:label {
bd:serviceParam wikibase:language "en" .
}
}
LIMIT 8000
Try it
Update:
Although not an answer to this specific question, anyone trying to get similar data to this should have a look here.
Update 2:
With help in the comments from #UninformedUser, the query is now:
SELECT DISTINCT ?city ?cityLabel ?country ?population ?countryLabel ?region ?regionLabel ?lat ?long
WHERE
{
?city wdt:P31/wdt:P279 wd:Q515 . # find instances of subclasses of city
?city (wdt:P131) ?region.
?region wdt:P31/wdt:P279 wd:Q10864048 .
?city p:P1082 ?populationStmt .
?populationStmt ps:P1082 ?population ; pq:P585 ?pop_date .
?city wdt:P17 ?country . # Also find the country of the city
?city p:P625 ?statement . # coordinate-location statement
?statement psv:P625 ?coordinate_node .
OPTIONAL { ?coordinate_node wikibase:geoLatitude ?lat. }
OPTIONAL { ?coordinate_node wikibase:geoLongitude ?long.}
FILTER NOT EXISTS {
?city p:P1082/pq:P585 ?pop_date_ .
FILTER (?pop_date_ > ?pop_date)
}
FILTER (?population > 100000) .
# choose language
SERVICE wikibase:label {
bd:serviceParam wikibase:language "en" .
}
}
LIMIT 8000
Try it

Why variable + Label is not working in SPARQL

In the examples of the SPARQL of Wikidata, we have this one:
SELECT ?h ?date
WHERE
{
?h wdt:P31 wd:Q5 .
?h wdt:P569 ?date .
OPTIONAL {?h wdt:P570 ?d }
FILTER (?date > "1880-01-01T00:00:00Z"^^xsd:dateTime)
FILTER (!bound(?d))
}
LIMIT 1000
I understand that if you put Label after the name of a variable it shows the label. So, I don't understand why this shows no output:
SELECT ?h ?hLabel ?date ...
Thank you in advance!
I am not aware of that specific feature for Label after the variable name.
However, for rdfs:label, you can to inculde the rdfs:label in your query. Add the following line: ?h rdfs:label ?hLabel.:
SELECT ?h ?hLabel ?date WHERE
{
?h wdt:P31 wd:Q5 .
?h wdt:P569 ?date .
?h rdfs:label ?hLabel.
OPTIONAL {?h wdt:P570 ?d }
FILTER (?date > "1880-01-01T00:00:00Z"^^xsd:dateTime)
FILTER (!bound(?d))
}
LIMIT 1000
If you want labels in a specific language, e.g. for English add FILTER (langMatches( lang(?hLabel), "EN" ) )
Here is a stackoverflow intersting answer about labels.