Retrieve only one label from set of individuals with multiple labels - sparql

Suppose I have the following set of individuals, where some of them have more than one rdfs:label:
Individual
Label
ind_01
"ind-001"
ind_02
"ind-002"
ind_02
"ind-2"
ind_03
"label3"
ind_04
"ind-4"
ind_04
"ind-04"
...
...
I would like to run a SPARQL query that retrieves only one label per individual, no matter which one (i.e., the choice can be totally arbitrary). Thus, a suitable output based on the above dataset would be:
Individual
Label
ind_01
"ind-001"
ind_02
"ind-002"
ind_03
"label3"
ind_04
"ind-4"
...
...

You could use SAMPLE, which "returns an arbitrary value from the multiset passed to it".
SELECT ?individual (SAMPLE(?label) AS ?label_sample)
WHERE {
?individual rdfs:label ?label .
}
GROUP BY ?individual

Related

SPARQL Restrict Number of Results for Specific Variable

Suppose I want to look for some first degree neighbors of Berlin. I ask the following query:
select ?s ?p where {
?s ?p dbr:Berlin.
}
Is it possible to put a restriction on the return result, such that there are at most 5 results for each unique value of ?p?
My attempts with subqueries all time out...
But, as potentially useful if not exactly perfect solution, maybe GROUP_CONCAT, MAX/MIN or SAMPLE are of use?
SELECT
?writer (GROUP_CONCAT(?namestring; SEPARATOR = " ") AS ?namestrings)
(MIN(?namestring) AS ?min_name)
(MAX(?namestring) AS ?max_name)
(SAMPLE(?namestring) AS ?random_name)
(SAMPLE(?namestring) AS ?another_random_name_that_may_unfortunately_be_the_same_again)
WHERE {
?writer wdt:P31 wd:Q5;
wdt:P166 wd:Q37922;
wdt:P735 ?firstname.
?firstname wdt:P1705 ?namestring.
}
GROUP BY ?writer
HAVING ((COUNT(?writer)) > 2 )
LIMIT 20
See it live here.
And, as you can see, SAMPLE is apparently evaluated only once, so using it repeatedly does not get you closer to five (different) samples.
(You can leave out the HAVING for your use. I only included it to restrict it to useful examples))

SPARQL for unique set of values from all columns and rows

I have a query that returns several columns, i.e.:
SELECT ?a ?b ?c
WHERE { ... }
Every column variable is an IRI. Obviously this returns a unique row for every combination of column values (note that values may not be unique to a column):
<urn:id:x:1> <urn:id:a:2> <urn:id:j:3>
<urn:id:x:1> <urn:id:a:2> <urn:id:j:4>
<urn:id:x:1> <urn:id:j:4> <urn:id:k:5>
<urn:id:y:2> <urn:id:j:4> <urn:id:k:6>
...
However, all I need are the unique IRIs spanning all rows and columns. i.e.:
<urn:id:x:1>
<urn:id:a:2>
<urn:id:j:3>
<urn:id:j:4>
<urn:id:k:5>
<urn:id:y:2>
<urn:id:k:6>
...
Is it possible to achieve this using SPARQL, or do I need to post-process the results to merge and de-deduplicate the values? Order is unimportant.
SELECT DISTINCT ?d {
...
VALUES ?i { 1 2 3 }
BIND (if(?i=1, ?a, if(?i=2, ?b, ?c)) AS ?d)
}
What does this do?
The VALUES clause creates three copies of each solution and numbers them with a variable ?i
The BIND clause creates a new variable ?d whose value is ?a, ?b or ?c, depending on whether ?i is 1, 2 or 3 in the given solution
The SELECT DISTINCT ?d returns only ?d and removes duplicates

How to Add and Subtract numbers using SPARQL?

Is there any function to sum and subtract two numbers (integer or long data types) from two different classes using SPARQL? how to use it ?
As AKSW is suggesting on the comment here it is an example query that adds two variables and projects the result in the total variable.
SELECT ?total
{ ?x ns:itemcount ?xcount .
?y ns:itemcount ?ycount.
BIND (?xcount + ?ycount AS ?total)
}
See SPARQL 1.1 for futher details

Why filter doesn't work in this context?

This is the query and the result:
As you see, I am filtering out the users that are bo:ania, so why do they still appear?
However, if I remove the widecard and select just the users ?user, bo:ania doesn't appear
I didn't provide a minimum data example because this is a question about how filter and wildcard work, not about a problem in extracting some data from a data set. However, if you need a minimum data, I'm more than happy to provide it.
?specificUser is bound to bo:ania by your VALUES statement. ?user is an entirely different binding defined by the other triple patterns. Your FILTER says to filter out results where ?user = bo:ania, and it appears to be doing that correctly, seeing that ?user is not bound to bo:ania in any of the results.
BTW, there isn't a need to use VALUES in this case unless you want to inspect multiple values. If it's just the one value, then the following would work, and not have you wondering why the binding to bo:ania is included in the result set:
SELECT *
WHERE {
?user a rs:user .
?user rs:hasRated ?rating .
?rating rs:hasRatingDate ?ratngDate .
FILTER (?ratingDates >= (now() -"P10000F"^^xsd:duration) )
FILTER (?user != bo:ania)
}

Order SPARQL query results by length of a string?

I'm trying to autocomplete what the user writes in an input, with terms in DBpedia, similar to this jsFiddle example. Try writing dog in the input of that jsFiddle, and you will see the 'Dog' term in the suggestions.
I have the following code, and the problem is that the 10-term list I got as a result does not contains the "Dog" alternative. So, if I could order the list by the length of the (string representation of) ?concept, then I could get that term. Is this possible?
SELECT DISTINCT ?concept
WHERE {
?concept a skos:Concept .
FILTER regex(str(?concept), "dog", "i")
}
ORDER BY ASC(?concept) LIMIT 10
So, if I could order the list by the lenght of the ?concept it is possible to get the term. But I can't find the right statement to do it. Is it possible?
It sounds like you're looking for strlen.
order by strlen(str(?concept))
E.g.,
select distinct ?concept where {
?concept a skos:Concept .
filter regex(str(?concept), "dog", "i")
}
order by strlen(str(?concept))
limit 10
SPARQL results
That said, if you're just checking string membership, you don't need all the power of regular expressions, and it might be more efficient to use contains and lcase to check whether the lowercased ?concept contains "dog" with a filter like:
filter contains(lcase(str(?concept)), "dog")
The table of contents in the SPARQL spec has a big list of functions that you can browse. In particular, you'd want to look at the subsections of 17.4 Function Definitions.