I'm using SPARQL and Wikidata query service to try and determine: The actors that got the Oscar award sorted by the total number of (any) awards they received in decreasing order with the list of all their awards.
So far this is what I have that works but doesn't quite do what the question is asking.
SELECT ?item ?itemLabel
WHERE {
?item wdt:P31 wd:Q5 .
?item wdt:P166 wd:Q103916 .
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
}
LIMIT 1000
And this I what I have that I am trying to get to work but is not yet working. Im new to this and any help is appreciated. Updated below query because I've gotten a bit closer
SELECT ?item ?itemLabel (COUNT (DISTINCT ?year) AS ?count)
WHERE {
?item wdt:P31 wd:Q5 .
?item wdt:P166 wd:Q103916 .
?item p:P585 ?year .
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
}
GROUP BY ?item ?itemLabel
ORDER BY ?count
LIMIT 100
Related
Let's say I'm looking for Wikidata cats who have their place of birth (P19) listed, using this query (also at https://w.wiki/5mdp):
SELECT ?item ?itemLabel ?placeofbirthLabel ?date
WHERE
{
?item wdt:P31 wd:Q146;
wdt:P19 ?placeofbirth;
schema:dateModified ?date.
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
}
This retrieves: item id, item label, (the label of) the place of birth, and the date that any part of the item was last updated.
What if I also want to retrieve the date that the place of birth (P19) was last edited?
Thanks in advance!
Place items can also have a schema:dateModified property:
SELECT ?item ?itemLabel ?item_modified ?placeofbirthLabel ?placeofbirth_modified
WHERE
{
?item wdt:P31 wd:Q146 ;
wdt:P19 ?placeofbirth ;
schema:dateModified ?item_modified .
?placeofbirth schema:dateModified ?placeofbirth_modified .
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" . }
} LIMIT 10
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". }
}
Like in the SQL aggregate MAX, MIN or FIRST, it gets only one value, not duplicating lines.
Real Wikidata case
Where the OPTIONAL clause expands from 253 to 257 lines:
# Countries and its codes
SELECT ?code ?item ?itemLabel ?osmId
WHERE
{
?item wdt:P297 ?code.
OPTIONAL{?item wdt:P402 ?osmId .}
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
ORDER BY ?code
try here
I need only one (any) osmId. How to do something like FIRST{OPTIONAL{?item wdt:P402 ?osmId .}} ?
NOTES:
it is not a duplicate of How to get only the most recent value from a Wikidata property?
it is not a duplicate of Why does this Wikidata SPARQL query only work for the first element in a list?
... no exactly need for simple "any first".
Here a WIKI answer (please you can edit to enhance this answer!)
# Countries and its codes
SELECT ?code ?item ?itemLabel
(MAX(?osmId) as ?osmId_max) (COUNT(?code) as ?osmId_n)
WHERE
{
?item wdt:P297 ?code.
OPTIONAL{?item wdt:P402 ?osmId .}
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
GROUP BY ?code ?item ?itemLabel
ORDER BY ?code
try
The COUNT(?code) is only to check the lines where osmId was not an Unique-ID.
Other simple solution to filter only the first option?
Using SAMPLE
As the #ValerioCocchi suggestion, we can use SAMPLE instead MAX:
SELECT ?code ?item ?itemLabel (SAMPLE(?osmId) as ?osmId_sample)
WHERE
{
?item wdt:P297 ?code.
OPTIONAL{?item wdt:P402 ?osmId .}
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
GROUP BY ?code ?item ?itemLabel
ORDER BY ?code
try
SAMPLE use a little bit less CPU-time, but the main motivation to use is when you don’t care which value is returned. In the case of Wikidata, when the property-value is to be unique but there are some (minimal) errors, and you can ignore them.
NOTE about the osmId: the advantage of MAX in this particular query, using an numeric ID related to a temporal sequence, is that it can be a "fresher" ID... But in OpenStreetMap (OSM) the strategy can be the inverse: most old is the most stable ID. So, SAMPLE make sense also in a context of ignorance about better strategy.
Using FILTER
The #StanislavKralin suggestion:
SELECT ?code ?item ?itemLabel ?osmId
WHERE
{
?item wdt:P297 ?code.
OPTIONAL{
?item wdt:P402 ?osmId
FILTER NOT EXISTS {
?item wdt:P402 ?osmId, ?osmId_ .
FILTER (?osmId_ > ?osmId)
}
}
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
ORDER BY ?code
try
Seems more verbose.
Please forgive me if I am using the wrong terminology to describe my problem.
I want to extract information on the world's island regions via WIKIDATA SPARQL query, including coordinates, the country they belong to, the archipelago they belong to and their GeoNamesIDs. Of course, this information is not provided for each and every island, so if I include it in my query, I am limiting my result list to items that already contain these properties:
SELECT ?item ?itemLabel ?coords ?GeoNamesID
WHERE {
?item wdt:P31 wd:Q23442.
?item wdt:P625 ?coords.
?item wdt:P1566 ?GeoNamesID.
?item wdt:P17 ?country.
?item wdt:P706 ?terrain.
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
}
How can I make some of these properties "optional" to display the values if they exist but still include items that do not have them at all?
I could not find any similar issue in the long list of Wikidata SPARQL examples and would appreciate your help.
Here is my updated query including several optional properties:
SELECT ?item ?itemLabel ?coords ?GeoNamesID ?country ?continent ?terrain ?date ?named ?archipelago
WHERE {
?item wdt:P31 wd:Q23442.
?item wdt:P625 ?coords.
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
OPTIONAL {?item wdt:P1566 ?GeoNamesID.}
OPTIONAL {?item wdt:P17 ?country.}
OPTIONAL {?item wdt:P30 ?continent.}
OPTIONAL {?item wdt:P706 ?terrain.}
OPTIONAL {?item wdt:P571 ?date.}
OPTIONAL {?item wdt:P138 ?named.}
OPTIONAL {?item wdt:P361 ?archipelago.}
}
I should note that I got a "time out" when first querying all optional properties. I had to retry. But it worked at once with a single optional item:
SELECT ?item ?itemLabel ?coords ?GeoNamesID
WHERE {
?item wdt:P31 wd:Q23442.
?item wdt:P625 ?coords.
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
OPTIONAL {?item wdt:P1566 ?GeoNamesID.}
}
With the Wikidata Query Service (which I am new to), I am trying to find items that have no value for a property. In this case, I am looking for instances of (P31) humans (Q5) with no sex or gender (P21). My code is really basic:
SELECT ?item ?itemLabel WHERE {
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
?item wdt:P21 wd:Q6581072.
?item wdt:P31 wd:Q5.
}
LIMIT 100
Line 3 restricts it to finding things with female as the sex or gender. What could I replace it with that would make it only find things with no value for P21? The guides that I've found and a bit of googling don't seem to have stuff about looking for things without a value for a given property.
As discussed in the comments...
SELECT ?item ?itemLabel
WHERE
{
SERVICE wikibase:label
{ bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" }
FILTER NOT EXISTS { ?item wdt:P21 ?val }
?item wdt:P31 wd:Q5
}
LIMIT 100