sparql count not existing properties as zero - sparql

Here is my query:
PREFIX : <http://example.org/ns#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT ?id ?name (count(?s) as ?count)
WHERE {
?t a :Tag ;
:hasId ?id ;
:hasName ?name
OPTIONAL { ?s :hasTag ?t ;
rdf:type ?type }
FILTER (?type in (:Client, :Project, :Staff))
} GROUP BY ?id ?name
Tags with no objects are not included in the result. How can I get them also without using union?
Performance is also important
The goal is to gather information about tags (id, name) and number of objects they assign to (if no such objects count must be 0). Tag data sample:
:tag912 :hasId "912"^^xsd:integer
:tag912 :hasName "Phones"
This tag is assigned to 6 objects.
This query works for me:
PREFIX : <http://example.org/ns#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT ?id ?name ?count
WHERE {
{
SELECT ?id ?name (count(?s) as ?count)
WHERE {
?t a :Tag ;
:hasId ?id ;
:hasName ?name .
?s :hasTag ?t ;
rdf:type ?type
FILTER (?type in (:Client, :Project, :Staff))
} GROUP BY ?id ?name
} UNION {
SELECT ?id ?name (0 as ?count)
WHERE {
?t a :Tag ;
:hasId ?id ;
:hasName ?name
FILTER not exists { ?s :hasTag ?t }
}
}
}
How can I use bindings here? Will it improve performance?
Thank you

Why not use UNION?
Aside from that, your query is focused on ?t tags and their ?id and ?name — so it's not surprising that results don't include ?s objects which lack ?t and hence lack any ?id and ?name…
I think this may get you going in the right direction —
PREFIX : <http://example.org/ns#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT ?id
?name
(count(?s) as ?count)
WHERE
{ ?s rdf:type ?type
FILTER ( ?type IN ( :Client, :Project, :Staff ) ) .
OPTIONAL { ?s :hasTag ?t .
?t rdf:type :Tag ;
:hasId ?id ;
:hasName ?name }
}
GROUP BY ?id ?name

You can check if ?s is bound in your filter:
PREFIX : <http://example.org/ns#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT ?id ?name (COUNT(?s) as ?count)
WHERE {
?t a :Tag ;
:hasId ?id ;
:hasName ?name .
OPTIONAL {
?s :hasTag ?t ;
rdf:type ?type .
}
FILTER (!BOUND(?s) || ?type in (:Client, :Project, :Staff))
} GROUP BY ?id ?name
I don't know if this is faster than a union (or a bunch of unions), however.

Related

Get birthplace and date of American investors from DBpedia people in SPARQL

I'm trying to get a list of Investors from the US, their birth dates, and places.
But the SPARQL code below doesn't seem to work. I tried it on both
DBpedia pages:
https://live.dbpedia.org/sparql or
https://dbpedia.org/snorql/
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX dbr: <http://dbpedia.org/resource/>
SELECT ?name ?birthPlace ?birthDate
WHERE {
?person a dbo:BusinessPerson, dbo:Entrepreneur, dbo:Investor .
?person dbo:birthPlace ?birthPlace .
?person dbo:birthDate ?birthDate .
?person dbo:country dbr:United_States .
?person rdfs:label ?name .
FILTER(LANG(?name) = 'en')
}
Can't find any good literature on this subject either so having trouble understanding what I should alter.
All advice is appreciated.
Try the following query here:
SELECT distinct ?person ?label ?birthPlace ?birthDate
WHERE {
{
?person rdf:type dbo:Person.
?person ?p dbr:Investor.
?person dbo:nationality dbr:United_States.
?person rdfs:label ?label. FILTER (lang(?label) = 'en')
OPTIONAL{?person dbp:birthPlace ?birthPlace.}
OPTIONAL{?person dbo:birthDate ?birthDate }
}
Union
{
?person rdf:type dbo:Person.
?person ?p dbo:Entrepreneur.
?person dbo:nationality dbr:United_States.
?person rdfs:label ?label. FILTER (lang(?label) = 'en')
OPTIONAL{?person dbp:birthPlace ?birthPlace.}
OPTIONAL{?person dbo:birthDate ?birthDate }
}
Union
{
?person rdf:type dbo:Person.
?person a dbo:BusinessPerson.
?person dbo:nationality dbr:United_States.
?person rdfs:label ?label. FILTER (lang(?label) = 'en')
OPTIONAL{?person dbp:birthPlace ?birthPlace.}
OPTIONAL{?person dbo:birthDate ?birthDate }
}
}
you can also try this equivalent query on wikidata SPARQL endpoint here:
SELECT ?person ?personLabel ?dob ?pobLabel
WHERE
{
?person wdt:P31 wd:Q5.
?person wdt:P106 wd:Q557880.
?person wdt:P27 wd:Q30.
OPTIONAL {?person wdt:P569 ?dob.}
OPTIONAL {?person wdt:P19 ?pob. }
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
}

Unable to see Max in SPARQL Query

Im trying to query a knowledge graph and im trying print the max occurrence of ?n in the result and i have tried running following query but it just doesn't prints anything
here is my SPARQL Query
PREFIX : <http://www.tafsirtabari.com/ontology#>
PREFIX RDF:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
select
?n
(MAX( xsd:int(?countOfSharedLikedItems)) as ?max)
(COUNT(?n) as ?countOfSharedLikedItems)
where {
?h :hasTheme :lugha .
?h RDF:type :Hadith .
?h :hasHadithNo ?o.
?p :isPartOfHadith ?h.
{
?p :hasNarratorSegment ?nc.
?nc :refersTo+/:hasName ?n.
}
Union
{
?p :hasRootNarratorSegment ?rnc.
?rnc :refersTo+/:hasName ?n.
}
}
i have also tried following by using group by ?n
PREFIX : <http://www.tafsirtabari.com/ontology#>
PREFIX RDF:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>
select
(MAX(?countOfSharedLikedItems) as ?max)
(COUNT(?n) as ?countOfSharedLikedItems)
where {
?h :hasTheme :lugha .
?h RDF:type :Hadith .
?h :hasHadithNo ?o.
?p :isPartOfHadith ?h.
{
?p :hasNarratorSegment ?nc.
?nc :refersTo+/:hasName ?n.
}
Union
{
?p :hasRootNarratorSegment ?rnc.
?rnc :refersTo+/:hasName ?n.
}
} group by ?n
You can try this
PREFIX : <http://www.tafsirtabari.com/ontology#>
select (COUNT(?o ) AS ?triples) where {
?k :heardFrom ?o
}
6. Which RAWI narrated most hadiths about TOPIC_A
PREFIX hash: <http://www.tafsirtabari.com/ontology#>
PREFIX W3:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX : <http://www.tafsirtabari.com/ontology#>
SELECT ?total WHERE{
select DISTINCT ?n (COUNT(?n) as ?total) where {
?commentary hash:mentions hash:اهل_المعرفه .
?segment hash:containsCommentary ?commentary.
?segment ?Fr ?h .
?h W3:type hash:Hadith.
?p :isPartOfHadith ?h.
{
?p :hasNarratorSegment ?nc.
?nc :refersTo+/:hasName ?n.
}
Union
{
?p :hasRootNarratorSegment ?rnc.
?rnc :refersTo+/:hasName ?n.
}
}GROUP BY ?n
}ORDER BY DESC(?total)
LIMIT 1

SPARQL DbPedia foaf:name

Trying to execute some queries but when searching for foaf:name resultset is empty. Here's my code:
SELECT DISTINCT ?uri ?string
WHERE {
?uri rdf:type ?x.
?uri foaf:name 'Cavallo domestico'#it .
OPTIONAL { ?uri rdfs:label ?string . FILTER (lang(?string) = 'it') }
}
page exist http://it.dbpedia.org/resource/Equus_caballus/html
Apparently seems it's not related with languages different than english but with foaf:name request. If I execute following, retrieving generic foaf:givenName, it works:
SELECT DISTINCT ?uri ?string
WHERE {
?uri rdf:type ?x.
?uri foaf:givenName 'Jimmy'#en .
OPTIONAL { ?uri rdfs:label ?string . FILTER (lang(?string) = 'en') }
}
I think this wasn't working when I first mentioned that it didn't in a comment, but, as AKSW points out, this seems to be working now. The rdfs:label property has the article titles in various languages, not the foaf:name, so you can do this to get the types of Horse:
select ?x ?type {
?x a ?type ;
rdfs:label "Equus caballus"#it
}
SPARQL results

Union of two selects in a SPARQL query

I'd like to do something like
{
SELECT ?page, "A" AS ?type WHERE
{
?s rdfs:label "Microsoft"#en;
foaf:page ?page
}
}
UNION
{
SELECT ?page, "B" AS ?type WHERE
{
?s rdfs:label "Apple"#en;
foaf:page ?page
}
}
But this gives a syntax error. How can I union two select queries in SPARQL?
You can union them like this:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT * WHERE
{
{
SELECT ?page ("A" AS ?type) WHERE
{
?s rdfs:label "Microsoft"#en;
foaf:page ?page
}
}
UNION
{
SELECT ?page ("B" AS ?type) WHERE
{
?s rdfs:label "Apple"#en;
foaf:page ?page
}
}
}
(check with the SPARQL validator)
However I don't think you need sub queries at all for this case. For example:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?page ?type WHERE
{
?s foaf:page ?page .
{ ?s rdfs:label "Microsoft"#en . BIND ("A" as ?type) }
UNION
{ ?s rdfs:label "Apple"#en . BIND ("B" as ?type) }
}
Based on #user205512's answer, here's one that works on Virtuoso:
SELECT * {
?s foaf:page ?page .
{
SELECT ?page ("A" AS ?type) {
?s rdfs:label "Microsoft"#en;
foaf:page ?page
}
} UNION {
SELECT ?page ("B" AS ?type) {
?s rdfs:label "Apple"#en;
foaf:page ?page
}
}
}
The trick was just do add an additional ?s foaf:page ?page triple outside of the UNION. This is obviously redundant, but it seems to avoid the Virtuoso bug, which is apparently caused when you have a “naked” UNION with subqueries.

sparql - get a list of cities in certain country from dbpedia

I want to get triples about cities, which are from certain country. How can I do that?
I tried:
CONSTRUCT { ?c rdfs:label ?name . ?c rdfs:comment ?desc }
WHERE {
?c dbpprop:wikiPageUsesTemplate <http://dbpedia.org/resource/Template:Infobox_settlement> .
?c rdfs:label ?name .
?c rdfs:comment ?desc .
?c <http://dbpedia.org/ontology/country> ?country . ?country a <http://dbpedia.org/resource/CountryName>
FILTER ( lang(?name) = "en" && lang(?desc) = "en" )
}
but no luck :/ how can i do this?
CONSTRUCT { ?c rdfs:label ?name }
WHERE {
?c dbpprop:wikiPageUsesTemplate <http://dbpedia.org/resource/Template:Infobox_settlement> .
?c rdfs:label ?name .
?c dbpedia-owl:country <http://dbpedia.org/resource/Country> .
OPTIONAL { ?c dbpedia-owl:areaCode ?areacode }
FILTER ( lang(?name) = "pl" && ?population > 5000)
}
Hope it will help :)