blob: 4c230dca285dc7e7b638e936fa01ede503d34051 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<title>Apache Jena - SPARQL Tutorial - Alternatives in a Pattern</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="/css/bootstrap.min.css" rel="stylesheet" media="screen">
<link href="/css/bootstrap-extension.css" rel="stylesheet" type="text/css">
<link href="/css/jena.css" rel="stylesheet" type="text/css">
<link rel="shortcut icon" href="/images/favicon.ico" />
<script src="https://code.jquery.com/jquery-2.2.4.min.js"
integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
crossorigin="anonymous"></script>
<script src="/js/jena-navigation.js" type="text/javascript"></script>
<script src="/js/bootstrap.min.js" type="text/javascript"></script>
<script src="/js/improve.js" type="text/javascript"></script>
</head>
<body>
<nav class="navbar navbar-default" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/index.html">
<img class="logo-menu" src="/images/jena-logo/jena-logo-notext-small.png" alt="jena logo">Apache Jena</a>
</div>
<div class="collapse navbar-collapse navbar-ex1-collapse">
<ul class="nav navbar-nav">
<li id="homepage"><a href="/index.html"><span class="glyphicon glyphicon-home"></span> Home</a></li>
<li id="download"><a href="/download/index.cgi"><span class="glyphicon glyphicon-download-alt"></span> Download</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-book"></span> Learn <b class="caret"></b></a>
<ul class="dropdown-menu">
<li class="dropdown-header">Tutorials</li>
<li><a href="/tutorials/index.html">Overview</a></li>
<li><a href="/documentation/fuseki2/index.html">Fuseki Triplestore</a></li>
<li><a href="/documentation/notes/index.html">How-To's</a></li>
<li><a href="/documentation/query/manipulating_sparql_using_arq.html">Manipulating SPARQL using ARQ</a></li>
<li><a href="/tutorials/rdf_api.html">RDF core API tutorial</a></li>
<li><a href="/tutorials/sparql.html">SPARQL tutorial</a></li>
<li><a href="/tutorials/using_jena_with_eclipse.html">Using Jena with Eclipse</a></li>
<li class="divider"></li>
<li class="dropdown-header">References</li>
<li><a href="/documentation/index.html">Overview</a></li>
<li><a href="/documentation/query/index.html">ARQ (SPARQL)</a></li>
<li><a href="/documentation/assembler/index.html">Assembler</a></li>
<li><a href="/documentation/tools/index.html">Command-line tools</a></li>
<li><a href="/documentation/rdfs/">Data with RDFS Inferencing</a></li>
<li><a href="/documentation/geosparql/index.html">GeoSPARQL</a></li>
<li><a href="/documentation/inference/index.html">Inference API</a></li>
<li><a href="/documentation/javadoc.html">Javadoc</a></li>
<li><a href="/documentation/ontology/">Ontology API</a></li>
<li><a href="/documentation/permissions/index.html">Permissions</a></li>
<li><a href="/documentation/extras/querybuilder/index.html">Query Builder</a></li>
<li><a href="/documentation/rdf/index.html">RDF API</a></li>
<li><a href="/documentation/rdfconnection/">RDF Connection - SPARQL API</a></li>
<li><a href="/documentation/io/">RDF I/O</a></li>
<li><a href="/documentation/rdfstar/index.html">RDF-star</a></li>
<li><a href="/documentation/shacl/index.html">SHACL</a></li>
<li><a href="/documentation/shex/index.html">ShEx</a></li>
<li><a href="/documentation/jdbc/index.html">SPARQL over JDBC</a></li>
<li><a href="/documentation/tdb/index.html">TDB</a></li>
<li><a href="/documentation/tdb2/index.html">TDB2</a></li>
<li><a href="/documentation/query/text-query.html">Text Search</a></li>
</ul>
</li>
<li class="drop down">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-book"></span> Javadoc <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="/documentation/javadoc.html">All Javadoc</a></li>
<li><a href="/documentation/javadoc/arq/">ARQ</a></li>
<li><a href="/documentation/javadoc_elephas.html">Elephas</a></li>
<li><a href="/documentation/javadoc/fuseki2/">Fuseki</a></li>
<li><a href="/documentation/javadoc/geosparql/">GeoSPARQL</a></li>
<li><a href="/documentation/javadoc/jdbc/">JDBC</a></li>
<li><a href="/documentation/javadoc/jena/">Jena Core</a></li>
<li><a href="/documentation/javadoc/permissions/">Permissions</a></li>
<li><a href="/documentation/javadoc/extras/querybuilder/">Query Builder</a></li>
<li><a href="/documentation/javadoc/shacl/">SHACL</a></li>
<li><a href="/documentation/javadoc/tdb/">TDB</a></li>
<li><a href="/documentation/javadoc/text/">Text Search</a></li>
</ul>
</li>
<li id="ask"><a href="/help_and_support/index.html"><span class="glyphicon glyphicon-question-sign"></span> Ask</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-bullhorn"></span> Get involved <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="/getting_involved/index.html">Contribute</a></li>
<li><a href="/help_and_support/bugs_and_suggestions.html">Report a bug</a></li>
<li class="divider"></li>
<li class="dropdown-header">Project</li>
<li><a href="/about_jena/about.html">About Jena</a></li>
<li><a href="/about_jena/architecture.html">Architecture</a></li>
<li><a href="/about_jena/citing.html">Citing</a></li>
<li><a href="/about_jena/team.html">Project team</a></li>
<li><a href="/about_jena/contributions.html">Related projects</a></li>
<li><a href="/about_jena/roadmap.html">Roadmap</a></li>
<li class="divider"></li>
<li class="dropdown-header">ASF</li>
<li><a href="http://www.apache.org/">Apache Software Foundation</a></li>
<li><a href="http://www.apache.org/foundation/sponsorship.html">Become a Sponsor</a></li>
<li><a href="http://www.apache.org/licenses/LICENSE-2.0">License</a></li>
<li><a href="http://www.apache.org/security/">Security</a></li>
<li><a href="http://www.apache.org/foundation/thanks.html">Thanks</a></li>
</ul>
</li>
<li id="edit"><a href="https://github.com/apache/jena-site/edit/main/source/tutorials/sparql_union.md" title="Edit this page on GitHub"><span class="glyphicon glyphicon-pencil"></span> Edit this page</a></li>
</ul>
</div>
</div>
</nav>
<div class="container">
<div class="row">
<div class="col-md-12">
<div id="breadcrumbs">
<ol class="breadcrumb">
<li><a href='/tutorials'>TUTORIALS</a></li>
<li class="active">SPARQL UNION</li>
</ol>
</div>
<h1 class="title">SPARQL Tutorial - Alternatives in a Pattern</h1>
<p>Another way of dealing with the semi-structured data is to query
for one of a number of possibilities. This section covers <code>UNION</code>
patterns, where one of a number of possibilities is tried.</p>
<h2 id="union---two-ways-to-the-same-data">UNION - two ways to the same data</h2>
<p>Both the vCard vocabulary and the FOAF vocabulary have properties
for people&rsquo;s names.  In vCard, it is vCard:FN, the &ldquo;formatted
name&rdquo;, and in FOAF, it is foaf:name. In this section, we will look
at a small set of data where the names of people can be given by
either the FOAF or the vCard vocabulary.</p>
<p>Suppose we have <a href="sparql_data/vc-db-3.ttl">an RDF graph</a> that contains name
information using both the vCard and FOAF vocabularies.</p>
<pre><code>@prefix foaf: &lt;http://xmlns.com/foaf/0.1/&gt; .
@prefix vcard: &lt;http://www.w3.org/2001/vcard-rdf/3.0#&gt; .
_:a foaf:name &quot;Matt Jones&quot; .
_:b foaf:name &quot;Sarah Jones&quot; .
_:c vcard:FN &quot;Becky Smith&quot; .
_:d vcard:FN &quot;John Smith&quot; .
</code></pre>
<p>A query to access the name information, when it can be in either
form, could be (<a href="sparql_data/q-union1.rq">q-union1.rq</a>):</p>
<pre><code>PREFIX foaf: &lt;http://xmlns.com/foaf/0.1/&gt;
PREFIX vCard: &lt;http://www.w3.org/2001/vcard-rdf/3.0#&gt;
SELECT ?name
WHERE
{
{ [] foaf:name ?name } UNION { [] vCard:FN ?name }
}
</code></pre>
<p>This returns the results:</p>
<pre><code>-----------------
| name |
=================
| &quot;Matt Jones&quot; |
| &quot;Sarah Jones&quot; |
| &quot;Becky Smith&quot; |
| &quot;John Smith&quot; |
-----------------
</code></pre>
<p>It didn&rsquo;t matter which form of expression was used for the name,
the ?name variable is set. This can be achieved using a <code>FILTER</code> as
this query (<a href="sparql_data/q-union1alt.rq">q-union-1alt.rq</a>) shows:</p>
<pre><code>PREFIX foaf: &lt;http://xmlns.com/foaf/0.1/&gt;
PREFIX vCard: &lt;http://www.w3.org/2001/vcard-rdf/3.0#&gt;
SELECT ?name
WHERE
{
[] ?p ?name
FILTER ( ?p = foaf:name || ?p = vCard:FN )
}
</code></pre>
<p>testing whether the property is one URI or another. The solutions
may not come out in the same order.  The first form is more likely
to be faster, depending on the data and the storage used, because
the second form may have to get all the triples from the graph to
match the triple pattern with unbound variables (or blank nodes) in
each slot, then test each <code>?p</code> to see if it matches one of the
values. It will depend on the sophistication of the query optimizer
as to whether it spots that it can perform the query more
efficiently and is able to pass the constraint down as well as to
the storage layer.</p>
<h2 id="union---remembering-where-the-data-was-found">UNION - remembering where the data was found.</h2>
<p>The example above used the same variable in each branch. If
different variables are used, the application can discover which
sub-pattern caused the match (<a href="sparql_data/q-union2.rq">q-union2.rq</a>):</p>
<pre><code>PREFIX foaf: &lt;http://xmlns.com/foaf/0.1/&gt;
PREFIX vCard: &lt;http://www.w3.org/2001/vcard-rdf/3.0#&gt;
SELECT ?name1 ?name2
WHERE
{
{ [] foaf:name ?name1 } UNION { [] vCard:FN ?name2 }
}
---------------------------------
| name1 | name2 |
=================================
| &quot;Matt Jones&quot; | |
| &quot;Sarah Jones&quot; | |
| | &quot;Becky Smith&quot; |
| | &quot;John Smith&quot; |
---------------------------------
</code></pre>
<p>This second query has retained information of where the name of the
person came from by assigning the name to different variables.</p>
<h2 id="optional-and-union">OPTIONAL and UNION</h2>
<p>In practice, <code>OPTIONAL</code> is more common than <code>UNION</code> but they both
have their uses. <code>OPTIONAL</code> are useful for augmenting the solutions
found, <code>UNION</code> is useful for concatenating the solutions from two
possibilities. They don&rsquo;t necessary return the information in the
same way:</p>
<p>Query(<a href="sparql_data/q-union3.rq">q-union3.rq</a>):</p>
<pre><code>PREFIX foaf: &lt;http://xmlns.com/foaf/0.1/&gt;
PREFIX vCard: &lt;http://www.w3.org/2001/vcard-rdf/3.0#&gt;
SELECT ?name1 ?name2
WHERE
{
?x a foaf:Person
OPTIONAL { ?x foaf:name ?name1 }
OPTIONAL { ?x vCard:FN ?name2 }
}
---------------------------------
| name1 | name2 |
=================================
| &quot;Matt Jones&quot; | |
| &quot;Sarah Jones&quot; | |
| | &quot;Becky Smith&quot; |
| | &quot;John Smith&quot; |
---------------------------------
</code></pre>
<p>but beware of using <code>?name</code> in each <code>OPTIONAL</code> because that is an
order-dependent query.</p>
<p><a href="sparql_datasets.html">Next: Named Graphs</a></p>
</div>
</div>
</div>
<footer class="footer">
<div class="container" style="font-size:80%" >
<p>
Copyright &copy; 2011&ndash;2022 The Apache Software Foundation, Licensed under the
<a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.
</p>
<p>
Apache Jena, Jena, the Apache Jena project logo, Apache and the Apache feather logos are trademarks of
The Apache Software Foundation.
<br/>
<a href="https://privacy.apache.org/policies/privacy-policy-public.html"
>Apache Software Foundation Privacy Policy</a>.
</p>
</div>
</footer>
<script type="text/javascript">
var link = $('a[href="' + this.location.pathname + '"]');
if (link != undefined)
link.parents('li,ul').addClass('active');
</script>
</body>
</html>