I am trying to use pie chart to show information in percentage using Wikidata - sparql

I am trying to use a pie chart to show the percentage of tennis players who use their right hand or left hand or both (to show the dominant hand).e.g I just need help with a working query that can show that 50% use their right and 40 percent use their left and 10 percent use both of their hands
SELECT (COUNT(?item1) AS ?total) (100*?item2/?total AS ?percent)
WHERE {
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE]". }
{
SELECT DISTINCT ?item WHERE {
?item1 p:P106 ?statement0.
?statement0 (ps:P106/(wdt:P279*)) wd:Q10833314.
?item2 p:P741 ?statement1.
?statement1 (ps:P741/(wdt:P279*)) wd:Q789447.
?item2 p:P741 ?statement2.
?statement2 (ps:P741/(wdt:P279*)) wd:Q3039938.
}
}
}

Related

Exact match of variable string in SPARQL Wikidata Query Service

Exact match of variable string in SPARQL Wikidata Query Service at https://query.wikidata.org does not give the the results I expected.
I was expecting I could do:
SELECT * {
hint:Query hint:optimizer "None" .
{ SELECT DISTINCT (xsd:string(?author_name_) AS ?author_name) { wd:Q5565155 skos:altLabel ?author_name_ . } }
?work wdt:P2093 ?author_name .
}
But I get no returned results from the Wikidata Query Service:
However, if I use the "=" comparison, I can match the strings:
SELECT * {
hint:Query hint:optimizer "None" .
{ SELECT DISTINCT (xsd:string(?author_name_) AS ?author_name) { wd:Q5565155 skos:altLabel ?author_name_ . } }
?work wdt:P50 wd:Q5565155 .
?work wdt:P2093 ?author_name__ .
FILTER (?author_name = ?author_name__)
}
With the current data in Wikidata, I get five rows returned in this query.
Another way to get this data is by using a BIND:
SELECT * {
BIND("Knudsen GM" AS ?author_name)
?work wdt:P2093 ?author_name .
}
I suppose there might be something wrong with the casting as this does not return anything:
SELECT * {
BIND(xsd:string("Knudsen GM") AS ?author_name)
?work wdt:P2093 ?author_name .
}
Combinations with xsd:string changed to STR or no conversion at all in the original query do neither yield result rows.

how to programmatically get all available information from a Wikidata entity?

I'm really new to wikidata. I just figured that wikidata uses a lot of reification.
Suppose we want to get all information available for Obama. If we are going to do it from DBpedia, we would just use a simple query:
select * where {<http://dbpedia.org/resource/Barack_Obama> ?p ?o .} This would return all the properties and values with Obama being the subject. Essentially the result is the same as this page: http://dbpedia.org/page/Barack_Obama while the query result is in a format I needed.
I'm wondering how to do the same thing with Wikidata. This is the Wikidata page for Obama: https://www.wikidata.org/wiki/Q76. Let's say I want all the statements on this page. But almost all the statements on this page are reified in that they have ranks and qualifiers, etc. For example, for the "educated at" part, it not only has the school, but also the "start time" and "end time" and all schools are ranked as normal since Obama is not in these schools anymore.
I could just get all the schools by getting the truthy statements (using https://query.wikidata.org):
SELECT ?school ?schoolLabel WHERE {
wd:Q76 wdt:P69 ?school .
SERVICE wikibase:label {
bd:serviceParam wikibase:language "en" .
}
}
The above query will simple return all the schools.
If I want to get the start time and end time of the school, I need to do this:
SELECT ?school ?schoolLabel ?start ?end WHERE {
wd:Q76 p:P69 ?school_statement .
?school_statement ps:P69 ?school .
?school_statement pq:P580 ?start .
?school_statement pq:P582 ?end .
SERVICE wikibase:label {
bd:serviceParam wikibase:language "en" .
}
}
But the thing is, without looking at the actual page, how would I know that the ?school_statement has pq:P580 and pq:P582, namely the "start time" and "end time"? And it all comes down to a question that how do I get all the information (including reification) from https://www.wikidata.org/wiki/Q76?
Ultimately, I would expect a table like this:
||predicate||object||objectLabel||qualifier1||qualifier1Value||qualifier2||qualifier2Value||...
you should probably go for the Wikidata data API (more specifically the wbgetentities module) instead of the SPARQL endpoint:
In your case:
https://www.wikidata.org/w/api.php?action=wbgetentities&format=json&ids=Q76
You should find all the qualifiers data you where looking for: example with entities.Q76.claims.P69.1
{ mainsnak:
{ snaktype: 'value',
property: 'P69',
datavalue:
{ value: { 'entity-type': 'item', 'numeric-id': 3273124, id: 'Q3273124' },
type: 'wikibase-entityid' },
datatype: 'wikibase-item' },
type: 'statement',
qualifiers:
{ P580:
[ { snaktype: 'value',
property: 'P580',
hash: 'a1db249baf916bb22da7fa5666d426954435256c',
datavalue:
{ value:
{ time: '+1971-01-01T00:00:00Z',
timezone: 0,
before: 0,
after: 0,
precision: 9,
calendarmodel: 'http://www.wikidata.org/entity/Q1985727' },
type: 'time' },
datatype: 'time' } ],
P582:
[ { snaktype: 'value',
property: 'P582',
hash: 'a065bff95f5cb3026ebad306b3df7587c8daa2e9',
datavalue:
{ value:
{ time: '+1979-01-01T00:00:00Z',
timezone: 0,
before: 0,
after: 0,
precision: 9,
calendarmodel: 'http://www.wikidata.org/entity/Q1985727' },
type: 'time' },
datatype: 'time' } ] },
'qualifiers-order': [ 'P580', 'P582' ],
id: 'q76$464382F6-E090-409E-B7B9-CB913F1C2166',
rank: 'normal' }
Then you might be interesting in ways to extract readable results from those results

Querying multiple graphs with aggregate Count and graph in results

Is it possible to count the occurrences of triples in multiple named graphs and return the results as rows in a table? Such as:
?g ?count ?sequence_count
-------- ------- ---------------
graph1 54 54
graph2 120 80
Here is the query that I tried.
SELECT ?g ?count ?sequence_count
FROM NAMED <graph1>
FROM NAMED <graph2>
WHERE {
{
select (COUNT(?identifier) as ?count) (COUNT(?sequence) as ?sequence_count)
WHERE { GRAPH ?g {
?identifier a <http://www.w3.org/2000/01/rdf-schema#Resource> .
OPTIONAL { ?identifier <urn:sequence> ?sequence }
} }
}
}
But the results were:
?g ?count ?sequence_count
-------- ------- ---------------
174 134
I'm trying to avoid having to write out:
select ?count_graph1 ?sequence_count_graph1 ?count_graph2 ...
as there could be hundreds of graphs to query.
First, the query is really close. Just move the SELECT inside of the graph statement - basically stating 'for each graph, find these aggregate values'. Second, if any of the ?identifier matches have multiple values, the count for ?identifier will have duplicates, so DISTINCT results are necessary. Try the following:
SELECT *
FROM NAMED <graph1>
FROM NAMED <graph2>
WHERE {
GRAPH ?g {
SELECT (COUNT(DISTINCT ?identifier) as ?count) (COUNT(?sequence) as ?sequence_count)
WHERE {
?identifier a <http://www.w3.org/2000/01/rdf-schema#Resource> .
OPTIONAL { ?identifier <urn:sequence> ?sequence }
}
}
}

Conditional subquery in SPIN function (SPARQL)

How do I change the query formula based on whether or not a variable is bound?
I am invoking the magic property like this:
WHERE {
VALUES (?subj) {
([my bound positional parameter value goes here...])
}
?subj :myMagicProperty ?result .
}
Inside the magic property, I do a union:
?result a :Rule .
{
?result :someProp ?subj .
}
UNION
{
FILTER NOT EXISTS {
?result :someProp ?anyValue .
}
}
In other words, get me all results where :someProp is this value or :someProp is not defined.
Here is the tricky part. If ?subj is unbound (i.e., I set it as UNDEF in the VALUES block), the above query goes wild and returns everything.
Instead, I want to check if ?subjis unbound. If ?subj is unbound, :myMagicProperty should only return the following results:
FILTER NOT EXISTS {
?result ?someProp ?anyValue .
}
I have experimented with using FILTER and the BOUND function, but I can't figure out how to get the correct behavior. How can I drop one of UNION clauses from my query when ?subj is not bound?
Updates
Revised the first query to add the VALUES block.
Added missing ?result a :Rule . statement.
Corrected ?someProp to :someProp.
First I'd like to confirm what your intent is. I'd like to do that by asking you to respond to the following query that you can run in TopBraid Composer.
SELECT *
WHERE { GRAPH <http://topbraid.org/examples/kennedys> {
VALUES (?property) {(kennedys:firstName) (kennedys:lastName) (UNDEF)}
{
FILTER(BOUND(?property) )
?s ?property ?result .
}
UNION
{
FILTER(!BOUND(?property))
BIND("not sure what you want to do in this case" AS ?result)
}
}
}
The difference in the code above to your code is that I am setting values of your ?someProp in the VALUES statement, whereas you are setting ?subj.
The UNIONed subgraphs are using BOUND and !BOUND as guards.
Before going further with help I'd like to hear from you with a clearer explanation of the query you are wanting to build. Then I can show you the magic property that will be needed.
It's this piece of your initial post I need to understand more:
Here is the tricky part. If ?subj is unbound (i.e., I set it as UNDEF in the VALUES block), the above query goes wild and returns everything.
Instead, I want to check if ?subj is unbound. If ?subj is unbound, myMagicProperty should only return the following results:
FILTER NOT EXISTS {
?result ?someProp ?anyValue .
}*
With ?someProp undefined, as well as ?result and ?anyValue, what were you expecting to come back? Also this subgraph of yours has no assertions that will populate the graph and therefore will return nothing.
Ralph
The trick is, I need to do the UNION using a variable different than the one passed in as an argument. This way, the UNION operation does not cause the unbound parameter to be bound. After the UNION, I can use a FILTER to control the results based on the input parameter.
SELECT ?result
WHERE {
?result a :Rule .
{
SELECT ?rule ?value ?anyValueMatch
WHERE {
{
?rule :someProp ?value .
BIND (false AS ?anyValueMatch) .
}
UNION
{
FILTER NOT EXISTS {
?rule :someProp ?any .
} .
BIND (true AS ?anyValueMatch) .
} .
}
} .
FILTER ((bound(?subj) && (?value = ?subj)) || (?anyValueMatch = true)) .
}
Another way to do this is with COALESCE:
SELECT ?result
WHERE {
?result a :Rule .
OPTIONAL {
?result :someProp ?value .
}
FILTER (COALESCE(?value = ?subj, !bound(?value)))
}
...this avoids the sub-select and simply filters to include only the ?result matches where '?value = ?subj', and if that clause fails the !bound() clause ensures matches that do not have a :someProp property are also included.

Sparql queries with two variables

How can I make a sparql query with 2 variables?
And let me explain:
I have an ontology for historical maps. My entities are:HistoricalMap , Language , Color
and the object properties that connect them are:hasLanguage , hasColor (the hist.map has language and has color).
If I make the query:
SELECT ?HistoricalMap ?Language ?Color
WHERE { ?HistoricalMap p1:hasLanguage ?Language.
?HistoricalMap p1:hasColor ?Color.
}
I get all the maps that have color and language.
How can i ask for the map that hasColor "Red" AND hasLanguage French?
Because you want "AND", you can just use constants in the pattern.
SELECT ?HistoricalMap
WHERE { ?HistoricalMap p1:hasLanguage "French".
?HistoricalMap p1:hasColor "Red" .
}
If you also want to return the variables still, use FILTER:
SELECT ?HistoricalMap ?Language ?Color
WHERE { ?HistoricalMap p1:hasLanguage ?Language.
?HistoricalMap p1:hasColor ?Color.
FILTER(?Language = "French" && ?Color = "Red")
}
you need to understand how the french language and the colour red are represented in your data.
it should be enough to see how they are returned when doing the query you have mentioned.
querying dbpedia, that would be, for instance:
SELECT ?entity
WHERE {
?entity dbpedia-owl:colour <http://dbpedia.org/resource/Red> .
?entity dbpedia-owl:language <http://dbpedia.org/resource/French_language> .
}