get all DISTINCT labels of an item - sparql

I'm trying to get all distinct labels of a Wikidata Item.
I know I can get all labels of an item with the following query:
SELECT DISTINCT ?team ?labels WHERE {
?team wdt:P31 wd:Q13393265.
?team rdfs:label ?labels.
}
LIMIT 10
Link to query
But how would I go about only getting distinct labels (so no duplicates)?
I've tried the following:
SELECT DISTINCT ?team ?labels WHERE {
?team wdt:P31 wd:Q13393265.
{
SELECT DISTINCT * WHERE
{
?team rdfs:label ?labels.
}
}
}
LIMIT 10
Link to query
But the results still contain duplicate labels.
PS: limits are only set, so queries are fast while debugging. Once it works as intended, there will not be a limit

Your first query actually does show distinct labels, but the way Wikidata displays the results doesn’t make it clear.
These four literals are different, but Wikidata will display "foobar" every time:
"foobar"
"foobar"#en
"foobar"#en-US
"foobar"#es
To display the language, you can use lang():
SELECT DISTINCT ?team ?label (lang(?label) AS ?language)
WHERE {
?team wdt:P31 wd:Q13393265.
?team rdfs:label ?label.
}
LIMIT 10
To ignore the language, you can use str(), which returns the lexical form:
SELECT DISTINCT ?team (str(?label) AS ?label_lexical)
WHERE {
?team wdt:P31 wd:Q13393265.
?team rdfs:label ?label.
}
LIMIT 10

Related

Group Concat using sparql query

Can some one help me how to use group_concat in sparql query. When i am using in the database it is pulling out iri from the data. How to pull the the labels for the objects present in the database using group_concat.
You will usually have IRIs with a label. Now, to return labels only, a query like this will work:
SELECT ?item ?label
WHERE {
?item rdfs:label ?label
}
Note that rdfs:label is conventionally used for labels, but any name can be used - it depends on the data that you have.
Now, imagine we want to find a GROUP_CONCAT of children's names, grouped by mother.
First, the query for the children and labels looks like this:
SELECT ?mother ?child ?label
WHERE {
?mother :hasChild ?child .
?child rdfs:label ?label .
}
Notice that ?mother and ?child will be bound to IRIs here, and ?label to a string.
Now for the GROUP_CONCAT, you will just need a query like:
SELECT ?mother (GROUP_CONCAT(?label; SEPARATOR=", ") AS ?concat)
WHERE {
?mother :hasChild ?child .
?child rdfs:label ?label .
}
GROUP BY ?mother

Wikidata Returning Multiple Results For Id

I am trying to get the label of a wikidata item using its id. My sparql looks like:
SELECT ?label
WHERE
{
wd:Q245068 rdfs:label ?label .
FILTER (langMatches( lang(?label), "EN" ) )
}
When I run this, I get 3 results that are all "comedian".
Why does this return multiple results for the same language/id?
Yes, that's funny...
The reason is obvious if you just check the item
"English" means three different things (here labeled in German, the international language of high comedy): Canadian, British, and American English. You get all three.
Here's how to avoid it:
SELECT DISTINCT ?label
WHERE {
wd:Q245068 rdfs:label ?label .
FILTER (langMatches( lang(?label), "EN" ) )
}
Or, use a more specific language code:
FILTER (langMatches( lang(?label), "EN-GB" ) )
But that runs the risk of not returning any label if it isn't set in the particular variety you've chosen. You can get around that, but really at the end you are just reimplementing the standard service that exists for exactly this purpose:
# just ad "Label" to get the label in the SELECT
SELECT ?item ?itemLabel
WHERE {
?item wet:P31 Q5.
# WITH THIS SERVICE
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}

How to express equals relation in sparql?

I am trying to use sparql to find all French labels of words that are related to a given English word.
The query I made is something like the following:
SELECT ?extword ?word ?label where {
?word rdfs:label "shark"#eng.
{?extword rdf:type ?word}
UNION
{?word rdf:type ?extword}.
?extword rdfs:label ?label filter(lang(?label)="fra")
}
While it does give me the French labels of the extword as desired, it does not give the French labels of word itself.
What I need is to insert a clause to express the relation that extword is exactly word, like this:
SELECT ?extword ?word ?label where {
?word rdfs:label "shark"#eng.
{?extword = ?word}
UNION
{?extword rdf:type ?word}
UNION
{?word rdf:type ?extword}.
?extword rdfs:label ?label filter(lang(?label)="fra")
}
It turns out to be syntax error. Is it possible to also include the French labels of word itself, without doing another query?
To be clearer, the result I expect is the result from my first query combined with result from the following query:
SELECT ?word ?label where {
?word rdfs:label "shark"#eng.
?word rdfs:label ?label filter(lang(?label)="fra")
}

Filtering results of SPARQL queries

I want to retrieve all 20th century italian novelists' name.
I've written this:
SELECT ?label
WHERE{
?novelist a yago:ItalianNovelists.
?novelist rdfs:label ?label.
FILTER (langMatches(lang(?label), "EN"))
}
ORDER BY ?label
How can i filter the results?
There are several options. Here I'd suggest two:
Use the pattern ?novelist dct:subject dbc:20th-century_novelists, if you can rely on that classification.
SELECT ?label
WHERE{
?novelist a yago:ItalianNovelists;
rdfs:label ?label;
dct:subject dbc:20th-century_novelists.
FILTER (langMatches(lang(?label), "EN"))
}
ORDER BY ?label
Define birth range or a life-span range. Example birth range:
SELECT ?label
WHERE{
?novelist a yago:ItalianNovelists;
rdfs:label ?label;
dbo:birthDate ?date.
BIND (YEAR(?date) AS ?year)
FILTER (langMatches(lang(?label), "EN"))
FILTER (?year > 1882 && ?year < 1972)
}
ORDER BY ?label
With option 2 you will get more results but depending on the range, they might include novelists who haven't published anything in 20th century.
A third option would be the filter by the year of publishing. However, I wouldn't recommend it. First, it will give only results for those for whom such information is currently available in DBpedia, and that subset would most likely be smaller than the one from the first option. Second, depending on how you would define a 20 century novelist, the query results will omit those who wrote a novel in 20 century, which was published in 21.
The language tag is in lowercase, so just replace "EN: with "en". Also, I find the following to be just as effective as using langMatches
FILTER (lang(?label) = "en")

SPARQL: selecting people by country

I am trying to select all people born in a specific country (e.g. Portugal) from DBPedia.
I could use this query:
SELECT DISTINCT ?person
WHERE {
?person dbpedia-owl:birthPlace dbpedia:Portugal.
}
But the problem is that not all people have dbpedia:Portugal as birthPlace. About 30% of people have just a town name as birthPlace, e.g.
dbpedia:Lisbon
I could add all Portugal cities in a FILTER clause but it's a big list.
May be it's possible to infer Portugal from Lisbon in the SPARQL query somehow?
(to not to add all Portugal cities in FILTER to get ALL persons)
If we assume all the cities in a specific country are defined as part of that country in dbpedia, you could have a query that first looks for the people that have dbpedia:Portugal as a country and then cities within dbpedia:Portugal.
SELECT DISTINCT ?person
WHERE {
?person a dbpedia-owl:Person.
Optional{
?person dbpedia-owl:birthPlace ?country.
}
Optional{
?person dbpedia-owl:birthPlace ?place.
?place dbpedia-owl:country ?country
}
filter(?country= dbpedia:Portugal)
}
The query that you have written identifies 1723 distinct URIs, and this finds 2563 URIs.
Artemis' answer works, but it's very verbose for what's a pretty simple query. It can be simplified to:
select distinct ?person where {
?person a dbpedia-owl:Person ;
dbpedia-owl:birthPlace/dbpedia-owl:country? dbpedia:Portugal
}
SPARQL results (2449)
Full results may be achieved by this http://answers.semanticweb.com/questions/22450/sparql-selecting-people-by-country
- 2730 persons
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
PREFIX dbpedia: <http://dbpedia.org/resource/>
SELECT ?person
WHERE
{
{?person a <http://dbpedia.org/ontology/Person>;
<http://dbpedia.org/ontology/birthPlace> ?place.
?place <http://dbpedia.org/ontology/country> ?birthCountry.
?birthCountry a <http://dbpedia.org/ontology/Country>.
FILTER (?birthCountry = dbpedia:Portugal).
}
UNION
{ ?person a <http://dbpedia.org/ontology/Person>;
<http://dbpedia.org/ontology/birthPlace> ?birthCountry.
?birthCountry a <http://dbpedia.org/ontology/Country>.
FILTER (?birthCountry = dbpedia:Portugal).
}
}
GROUP BY ?person
ORDER BY ?person