Using SPARQL "from" with both a graph and a graph group in Virtuoso 7.20.3217 - sparql

I have a graph group <group> of m graphs <group_1>...<group_m> with n total triples. When I do a count together with a graph <graph> with k total triples outside of the graph group, I only get the number of triples n in the graph group:
select count(*)
from <group>
from <graph>
{?s ?p ?o}
Result: n
When I list the graphs in the graph group explicitly, however, I get the correct result:
select count(*)
from <group_1>
from <group_2>
...
from <group_m>
from <graph>
{?s ?p ?o}
Result: n + k
How can I obtain the correct result with the graph group and what is the reason for this behaviour?

You should use either two subqueries like this for example:
select ?n ?k (?n + ?k as ?totalCount) where {
{ select (count(*) as ?n) where {
graph group: { ?s ?p ?o } }
{ select (count(*) as ?k) where {
graph graph: { ?s ?p ?o } }
}
Or use a union:
select (count(?s1) as ?n)
(count(?s2) as ?k)
(?n + ?k as ?totalCount)
where {
{ graph group: { ?s1 ?p1 ?o1 } }
union
{ graph graph: { ?s2 ?p2 ?o2 } }
}

Related

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

Is there a WITH clause in SPARQL?

Is there any analog of view creation or WITH clause from SQL in SPARQL?
I want to:
Select some data from table;
Select data which is not in the first selection (by subject) from the same table.
This seems to work without "WITH" but i do two similar SELECT query:
SELECT *
FROM NAMED <http://...>
{
{
SELECT DISTINCT ?s ?p ?o
WHERE {
BIND (<http://www.w3.org/2004/02/skos/core#prefLabel> AS ?p)
{ ?s <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2004/02/skos/core#Concept> . }
FILTER(LANGMATCHES(LANG(?o), "ru"))
}
ORDER BY ?o
}
UNION
{
SELECT DISTINCT ?s ?p ?o
WHERE {
BIND (<http://www.w3.org/2004/02/skos/core#prefLabel> AS ?p)
{ ?s <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2004/02/skos/core#Concept> . }
FILTER(LANGMATCHES(LANG(?o), "en"))
MINUS {
SELECT DISTINCT ?s
WHERE {
BIND (<http://www.w3.org/2004/02/skos/core#prefLabel> AS ?p)
{ ?s <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2004/02/skos/core#Concept> . }
FILTER(LANGMATCHES(LANG(?o), "ru"))
}
}
}
ORDER BY ?o
}
}

Blank node skolemization in SPARQL without iteration

Is it possible to implement blank node skolemization in SPARQL without iteration? It seems to me that iteration is required to skolemize chains of blank nodes, such as:
#prefix : <http://example.com/> .
[ a :A ;
:p1 [
a :B
]
] .
A SPARQL Update operation for skolemization can start from the blank nodes that appear as subjects only in triples without blank node objects:
DELETE {
?b1 ?outP ?outO .
?inS ?inP ?b1 .
}
INSERT {
?iri ?outP ?outO .
?inS ?inP ?iri .
}
WHERE {
{
SELECT ?b1 (uuid() AS ?iri)
WHERE {
{
SELECT DISTINCT ?b1
WHERE {
?b1 ?p1 [] .
FILTER isBlank(?b1)
FILTER NOT EXISTS {
?b1 ?p2 ?b2 .
FILTER isBlank(?b2)
}
}
}
}
}
?b1 ?outP ?outO .
OPTIONAL {
?inS ?inP ?b1 .
}
}
This operation can be repeated until no blank nodes are found in the data:
ASK {
?bnode ?p [] .
FILTER isBlank(?bnode)
}
Is it possible to avoid the iteration and implement the blank node skolemization in a single SPARQL Update operation?
(Also, this approach assumes there are no "orphan" blank nodes (i.e. blank nodes that appear only as objects).)
I found a two-step solution skolemising subjects and objects separately and storing the blank node aliases (links between blank nodes and IRIs via owl:sameAs) as intermediate data:
PREFIX : <http://example.com/>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
####################
# Rewrite subjects #
####################
DELETE {
?bnode ?p ?o .
}
INSERT {
?iri ?p ?o .
GRAPH :aliases {
?bnode owl:sameAs ?iri .
}
}
WHERE {
{
SELECT ?bnode (uuid() AS ?iri)
WHERE {
{
SELECT DISTINCT ?bnode
WHERE {
?bnode ?p [] .
FILTER isBlank(?bnode)
}
}
}
}
?bnode ?p ?o .
}
;
###################
# Rewrite objects #
###################
DELETE {
?s ?p ?bnode .
}
INSERT {
?s ?p ?iri .
}
WHERE {
{
SELECT ?bnode ?iri
WHERE {
{
SELECT DISTINCT ?bnode
WHERE {
[] ?p ?bnode .
FILTER isBlank(?bnode)
}
}
OPTIONAL {
GRAPH :aliases {
?bnode owl:sameAs ?_iri .
}
}
BIND (coalesce(?_iri, uuid()) AS ?iri)
}
}
?s ?p ?bnode .
}
;
############################
# Clear blank node aliases #
############################
CLEAR GRAPH :aliases

Sparql about dbpedia:World_Wide_Web

I'm new to the semantic web and I'm trying to figure out how to write a SPARQL query to extract from dbpedia everything about a particular subject. Not just it's proprieties, but also everything related to it.
I'm not even sure how to start such a query.
I would like to get all triples about the World Wide Web.
PREFIX dbpedia: <http://dbpedia.org/resource/>
SELECT DISTINCT ?s ?p ?o
WHERE {
?s ?p ?o .
?s ?p dbpedia:World_Wide_Web
# FILTER( lang(?s) = "en" ) -- doesn't work with filter
}Limit 100
This only returns some triples with a owl:sameAs predicate
Can you help me?
You can get all the triples that have dbpedia:World_Wide_Web as their subject or object with a query like this (this only gives 1000, of course). For any objects that are literals, we can restrict their language value:
select ?s ?p ?o where {
values ?web { dbpedia:World_Wide_Web }
{ ?web ?p ?o bind( ?web as ?s ) } union
{ ?s ?p ?web bind( ?web as ?o ) }
# for literal objects, take only English ones
filter( !isLiteral(?o) || langMatches(lang(?o),'en') )
}
limit 1000
SPARQL results
This includes results like the following, which seems to align with what you mentioned in the comments:
http://dbpedia.org/resource/World_Wide_Web http://dbpedia.org/property/company http://dbpedia.org/resource/CERN
http://dbpedia.org/resource/World_Wide_Web http://dbpedia.org/property/inventor http://dbpedia.org/resource/Tim_Berners-Lee
That will produce a lot of results, so you might want to restrict the properties that you can use. You should be able to do the following, but on the current DBpedia endpoint, it causes an error.
select ?s ?p ?o where {
values ?web { dbpedia:World_Wide_Web }
values ?p { rdf:type dbpedia-owl:abstract }
{ ?web ?p ?o bind( ?web as ?s ) } union
{ ?s ?p ?web bind( ?web as ?o ) }
}
limit 1000
Virtuoso 37000 Error SP031: SPARQL compiler: Internal error: sparp_gp_attach_filter_cbk(): attempt to attach a filter with used variable
SPARQL query:
define sql:big-data-const 0
#output-format:text/html
define sql:signal-void-variables 1 define input:default-graph-uri <http://dbpedia.org> select ?s ?p ?o where {
values ?web { dbpedia:World_Wide_Web }
values ?p { rdf:type dbpedia-owl:abstract }
{ ?web ?p ?o bind( ?web as ?s ) } union
{ ?s ?p ?web bind( ?web as ?o ) }
}
limit 1000
Instead, as a workaround, you can do this:
select ?s ?p ?o where {
values ?web { dbpedia:World_Wide_Web }
{ ?web ?p ?o bind( ?web as ?s ) }
union
{ ?s ?p ?web bind( ?web as ?o ) }
filter( ?p in (rdf:type, dbpedia-owl:abstract )) ###
}
limit 1000
SPARQL results

UNION operator in SPARQL updates

I have two SPARQL updates.First one:
INSERT
{ GRAPH <[http://example/bookStore2]> { ?book ?p ?v } }
WHERE
{ GRAPH <[http://example/bookStore]>
{ ?book dc:date ?date .
FILTER ( ?date > "1970-01-01T00:00:00-02:00"^^xsd:dateTime )
?book ?p ?v
} }
Second:
INSERT
{ GRAPH <[http://example/bookStore2]> { ?book ?p ?v } }
WHERE
{ GRAPH <[http://example/bookStore3]>
{ ?book dc:date ?date .
FILTER ( ?date > "1980-01-01T00:00:00-02:00"^^xsd:dateTime )
?book ?p ?v
} }
Can i combine them with the UNION operator? And if yes, is it an equivalent result? Is it possible to use UNION in SPARQL updates such as in "Select"?
AndyS's answer is correct; you can combine them, and the description of UNION is found in section 7 Matching Alternatives of the SPARQL specification. The combined query would be:
INSERT {
GRAPH <[http://example/bookStore2]> { ?book ?p ?v }
}
WHERE{
{
GRAPH <[http://example/bookStore]> {
?book dc:date ?date .
FILTER ( ?date > "1970-01-01T00:00:00-02:00"^^xsd:dateTime )
?book ?p ?v
}
}
UNION
{
GRAPH <[http://example/bookStore3]> {
?book dc:date ?date .
FILTER ( ?date > "1980-01-01T00:00:00-02:00"^^xsd:dateTime )
?book ?p ?v
}
}
}
In this particular case where the patterns are so similar, you could also just abstract out the differing parts with VALUES:
INSERT {
GRAPH <[http://example/bookStore2]> { ?book ?p ?v }
}
WHERE{
values (?graph ?startDate) {
(<[http://example/bookStore]> "1970-01-01T00:00:00-02:00"^^xsd:dateTime)
(<[http://example/bookStore3]> "1980-01-01T00:00:00-02:00"^^xsd:dateTime)
}
GRAPH ?graph {
?book dc:date ?date .
FILTER ( ?date > ?startDate )
?book ?p ?v
}
}
The WHERE clause is the same as SPARQL Query - you can use UNION.