blob: 58284ab6bfe224667435eb91da7c2e7aa7a99a90 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<title>Apache Jena - SPARQL Tutorial - Optional Information</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-icons.css" rel="stylesheet" media="screen"><link rel="stylesheet" type="text/css" href="https://jena.apache.org/sass/jena.1b17c39a117e22b46db4c66f6395dc27c134a60377d87d2d5745b8600eb69722.css" integrity="sha256-GxfDmhF&#43;IrRttMZvY5XcJ8E0pgN32H0tV0W4YA62lyI=">
<link rel="shortcut icon" href="/images/favicon.ico" />
</head>
<body>
<nav class="navbar navbar-expand-lg bg-body-tertiary" role="navigation">
<div class="container">
<div class="navbar-header">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></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" id="navbarNav">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li id="homepage" class="nav-item"><a class="nav-link" href="/index.html"><span class="bi-house"></span> Home</a></li>
<li id="download" class="nav-item"><a class="nav-link" href="/download/index.cgi"><span class="bi-download"></span> Download</a></li>
<li class="nav-item dropdown">
<a href="#" class="nav-link dropdown-toggle" role="button" data-bs-toggle="dropdown" aria-expanded="false"><span class="bi-journal"></span> Learn <b class="caret"></b></a>
<ul class="dropdown-menu">
<li class="dropdown-header">Tutorials</li>
<li><a class="dropdown-item" href="/tutorials/index.html">Overview</a></li>
<li><a class="dropdown-item" href="/documentation/fuseki2/index.html">Fuseki Triplestore</a></li>
<li><a class="dropdown-item" href="/documentation/notes/index.html">How-To's</a></li>
<li><a class="dropdown-item" href="/documentation/query/manipulating_sparql_using_arq.html">Manipulating SPARQL using ARQ</a></li>
<li><a class="dropdown-item" href="/tutorials/rdf_api.html">RDF core API tutorial</a></li>
<li><a class="dropdown-item" href="/tutorials/sparql.html">SPARQL tutorial</a></li>
<li><a class="dropdown-item" href="/tutorials/using_jena_with_eclipse.html">Using Jena with Eclipse</a></li>
<li class="dropdown-divider"></li>
<li class="dropdown-header">References</li>
<li><a class="dropdown-item" href="/documentation/index.html">Overview</a></li>
<li><a class="dropdown-item" href="/documentation/query/index.html">ARQ (SPARQL)</a></li>
<li><a class="dropdown-item" href="/documentation/io/">RDF I/O</a></li>
<li><a class="dropdown-item" href="/documentation/assembler/index.html">Assembler</a></li>
<li><a class="dropdown-item" href="/documentation/tools/index.html">Command-line tools</a></li>
<li><a class="dropdown-item" href="/documentation/rdfs/">Data with RDFS Inferencing</a></li>
<li><a class="dropdown-item" href="/documentation/geosparql/index.html">GeoSPARQL</a></li>
<li><a class="dropdown-item" href="/documentation/inference/index.html">Inference API</a></li>
<li><a class="dropdown-item" href="/documentation/ontology/">Ontology API</a></li>
<li><a class="dropdown-item" href="/documentation/permissions/index.html">Permissions</a></li>
<li><a class="dropdown-item" href="/documentation/extras/querybuilder/index.html">Query Builder</a></li>
<li><a class="dropdown-item" href="/documentation/rdf/index.html">RDF API</a></li>
<li><a class="dropdown-item" href="/documentation/rdfconnection/">RDF Connection - SPARQL API</a></li>
<li><a class="dropdown-item" href="/documentation/rdfstar/index.html">RDF-star</a></li>
<li><a class="dropdown-item" href="/documentation/shacl/index.html">SHACL</a></li>
<li><a class="dropdown-item" href="/documentation/shex/index.html">ShEx</a></li>
<li><a class="dropdown-item" href="/documentation/tdb/index.html">TDB</a></li>
<li><a class="dropdown-item" href="/documentation/tdb2/index.html">TDB2</a></li>
<li><a class="dropdown-item" href="/documentation/query/text-query.html">Text Search</a></li>
</ul>
</li>
<li class="nav-item dropdown">
<a href="#" class="nav-link dropdown-toggle" role="button" data-bs-toggle="dropdown" aria-expanded="false"><span class="bi-journal-code"></span> Javadoc <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="/documentation/javadoc.html">All Javadoc</a></li>
<li><a class="dropdown-item" href="/documentation/javadoc/arq/">ARQ</a></li>
<li><a class="dropdown-item" href="/documentation/javadoc/fuseki2/">Fuseki</a></li>
<li><a class="dropdown-item" href="/documentation/javadoc/geosparql/">GeoSPARQL</a></li>
<li><a class="dropdown-item" href="/documentation/javadoc/jena/">Jena Core</a></li>
<li><a class="dropdown-item" href="/documentation/javadoc/permissions/">Permissions</a></li>
<li><a class="dropdown-item" href="/documentation/javadoc/extras/querybuilder/">Query Builder</a></li>
<li><a class="dropdown-item" href="/documentation/javadoc/shacl/">SHACL</a></li>
<li><a class="dropdown-item" href="/documentation/javadoc/tdb/">TDB</a></li>
<li><a class="dropdown-item" href="/documentation/javadoc/text/">Text Search</a></li>
</ul>
</li>
</ul>
<form class="d-flex" role="search" action="/search" method="GET">
<div class="input-group">
<input class="form-control border-end-0 border m-0" type="search" name="q" id="search-query" placeholder="Search...." aria-label="Search" style="width: 10rem;">
<button class="btn btn-outline-secondary border-start-0 border" type="submit">
<i class="bi-search"></i>
</button>
</div>
</form>
<ul class="navbar-nav">
<li id="ask" class="nav-item"><a class="nav-link" href="/help_and_support/index.html" title="Ask"><span class="bi-patch-question"></span><span class="text-body d-none d-xxl-inline"> Ask</span></a></li>
<li class="nav-item dropdown">
<a href="#" title="Get involved" class="nav-link dropdown-toggle" role="button" data-bs-toggle="dropdown" aria-expanded="false"><span class="bi-megaphone"></span><span class="text-body d-none d-xxl-inline"> Get involved </span><b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="/getting_involved/index.html">Contribute</a></li>
<li><a class="dropdown-item" href="/help_and_support/bugs_and_suggestions.html">Report a bug</a></li>
<li class="dropdown-divider"></li>
<li class="dropdown-header">Project</li>
<li><a class="dropdown-item" href="/about_jena/about.html">About Jena</a></li>
<li><a class="dropdown-item" href="/about_jena/architecture.html">Architecture</a></li>
<li><a class="dropdown-item" href="/about_jena/citing.html">Citing</a></li>
<li><a class="dropdown-item" href="/about_jena/team.html">Project team</a></li>
<li><a class="dropdown-item" href="/about_jena/contributions.html">Related projects</a></li>
<li><a class="dropdown-item" href="/about_jena/roadmap.html">Roadmap</a></li>
<li><a class="dropdown-item" href="/about_jena/security-advisories.html">Security Advisories</a></li>
<li class="dropdown-divider"></li>
<li class="dropdown-header">ASF</li>
<li><a class="dropdown-item" href="https://www.apache.org/">Apache Software Foundation</a></li>
<li><a class="dropdown-item" href="https://www.apache.org/foundation/sponsorship.html">Become a Sponsor</a></li>
<li><a class="dropdown-item" href="https://www.apache.org/licenses/LICENSE-2.0">License</a></li>
<li><a class="dropdown-item" href="https://www.apache.org/security/">Security</a></li>
<li><a class="dropdown-item" href="https://www.apache.org/foundation/thanks.html">Thanks</a></li>
</ul>
</li>
<li class="nav-item" id="edit"><a class="nav-link" href="https://github.com/apache/jena-site/edit/main/source/tutorials/sparql_optionals.md" title="Edit this page on GitHub"><span class="bi-pencil-square"></span><span class="text-body d-none d-xxl-inline"> Edit this page</span></a></li>
</ul>
</div>
</div>
</nav>
<div class="container">
<div class="row">
<div class="col-md-12">
<div id="breadcrumbs">
<ol class="breadcrumb mt-4 p-2 bg-body-tertiary">
<li class="breadcrumb-item"><a href='/tutorials'>TUTORIALS</a></li>
<li class="breadcrumb-item active">SPARQL OPTIONALS</li>
</ol>
</div>
<h1 class="title">SPARQL Tutorial - Optional Information</h1>
<main class="d-flex flex-xl-row flex-column">
<aside class="text-muted align-self-start mb-3 p-0 d-xl-none d-block">
<h2 class="h6 sticky-top m-0 p-2 bg-body-tertiary">On this page</h2>
<nav id="TableOfContents">
<ul>
<li><a href="#optionals">OPTIONALs</a></li>
<li><a href="#optionals-with-filters">OPTIONALs with FILTERs</a></li>
<li><a href="#optionals-and-order-dependent-queries">OPTIONALs and Order Dependent Queries</a></li>
</ul>
</nav>
</aside>
<article class="flex-column me-lg-4">
<p>RDF is semi-structured data so SPARQL has a the ability to query
for data but not to fail query when that data does not exist. The
query is using an optional part to extend the information found in
a query solution but to return the non-optional information
anyway.</p>
<h2 id="optionals">OPTIONALs</h2>
<p>This query (<a href="sparql_data/q-opt1.rq">q-opt1.rq</a>) gets the name of a person and
also their age if that piece of information is available.</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sparql" data-lang="sparql"><span style="display:flex;"><span><span style="color:#a2f;font-weight:bold">PREFIX</span> <span style="color:#00f;font-weight:bold">info</span>: <span style="color:#a0a000">&lt;http://somewhere/peopleInfo#&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#a2f;font-weight:bold">PREFIX</span> <span style="color:#00f;font-weight:bold">vcard</span>: <span style="color:#a0a000">&lt;http://www.w3.org/2001/vcard-rdf/3.0#&gt;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a2f;font-weight:bold">SELECT</span> <span style="color:#b8860b">?name</span> <span style="color:#b8860b">?age</span>
</span></span><span style="display:flex;"><span><span style="color:#a2f;font-weight:bold">WHERE</span>
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span> <span style="color:#b8860b">?person</span> <span style="color:#00f;font-weight:bold">vcard</span>:<span style="color:#008000;font-weight:bold">FN</span> <span style="color:#b8860b">?name</span> .
</span></span><span style="display:flex;"><span> <span style="color:#a2f;font-weight:bold">OPTIONAL</span> { <span style="color:#b8860b">?person</span> <span style="color:#00f;font-weight:bold">info</span>:<span style="color:#008000;font-weight:bold">age</span> <span style="color:#b8860b">?age</span> }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Two of the four people in the data (<a href="sparql_data/vc-db-2.rdf">vc-db-2.rdf</a>)have
age properties so two of the query solutions have that
information. However, because the triple pattern for the age is
optional, there is a pattern solution for the people who don&rsquo;t have
age information.</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-turtle" data-lang="turtle"><span style="display:flex;"><span><span style="">------------------------</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">|</span><span style="color:#bbb"> </span><span style="">name</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb"> </span><span style="">age</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">=======================</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">|</span><span style="color:#bbb"> </span><span style="color:#b44">&#34;Becky Smith&#34;</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb"> </span><span style="color:#666">23</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">|</span><span style="color:#bbb"> </span><span style="color:#b44">&#34;Sarah Jones&#34;</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">|</span><span style="color:#bbb"> </span><span style="color:#b44">&#34;John Smith&#34;</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb"> </span><span style="color:#666">25</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">|</span><span style="color:#bbb"> </span><span style="color:#b44">&#34;Matt Jones&#34;</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">-----------------------</span><span style="color:#bbb">
</span></span></span></code></pre></div><p>If the optional clause had not been there, no age information would
have been retrieved. If the triple pattern had been included but
not optional then we would have the query
(<a href="sparql_data/q-opt2.rq">q-opt2.rq</a>):</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sparql" data-lang="sparql"><span style="display:flex;"><span><span style="color:#a2f;font-weight:bold">PREFIX</span> <span style="color:#00f;font-weight:bold">info</span>: <span style="color:#a0a000">&lt;http://somewhere/peopleInfo#&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#a2f;font-weight:bold">PREFIX</span> <span style="color:#00f;font-weight:bold">vcard</span>: <span style="color:#a0a000">&lt;http://www.w3.org/2001/vcard-rdf/3.0#&gt;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a2f;font-weight:bold">SELECT</span> <span style="color:#b8860b">?name</span> <span style="color:#b8860b">?age</span>
</span></span><span style="display:flex;"><span><span style="color:#a2f;font-weight:bold">WHERE</span>
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span> <span style="color:#b8860b">?person</span> <span style="color:#00f;font-weight:bold">vcard</span>:<span style="color:#008000;font-weight:bold">FN</span> <span style="color:#b8860b">?name</span> .
</span></span><span style="display:flex;"><span> <span style="color:#b8860b">?person</span> <span style="color:#00f;font-weight:bold">info</span>:<span style="color:#008000;font-weight:bold">age</span> <span style="color:#b8860b">?age</span> .
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>with only two solutions:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-turtle" data-lang="turtle"><span style="display:flex;"><span><span style="">-----------------------</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">|</span><span style="color:#bbb"> </span><span style="">name</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb"> </span><span style="">age</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">=======================</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">|</span><span style="color:#bbb"> </span><span style="color:#b44">&#34;Becky Smith&#34;</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb"> </span><span style="color:#666">23</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">|</span><span style="color:#bbb"> </span><span style="color:#b44">&#34;John Smith&#34;</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb"> </span><span style="color:#666">25</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">-----------------------</span><span style="color:#bbb">
</span></span></span></code></pre></div><p>because the <code>info:age</code> property must now be present in a solution.</p>
<h2 id="optionals-with-filters">OPTIONALs with FILTERs</h2>
<p><code>OPTIONAL</code> is a binary operator that combines two graph patterns.
The optional pattern is any group pattern and may involve any
SPARQL pattern types. If the group matches, the solution is
extended, if not, the original solution is given
(<a href="sparql_data/q-opt3.rq">q-opt3.rq</a>).</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sparql" data-lang="sparql"><span style="display:flex;"><span><span style="color:#a2f;font-weight:bold">PREFIX</span> <span style="color:#00f;font-weight:bold">info</span>: <span style="color:#a0a000">&lt;http://somewhere/peopleInfo#&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#a2f;font-weight:bold">PREFIX</span> <span style="color:#00f;font-weight:bold">vcard</span>: <span style="color:#a0a000">&lt;http://www.w3.org/2001/vcard-rdf/3.0#&gt;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a2f;font-weight:bold">SELECT</span> <span style="color:#b8860b">?name</span> <span style="color:#b8860b">?age</span>
</span></span><span style="display:flex;"><span><span style="color:#a2f;font-weight:bold">WHERE</span>
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span> <span style="color:#b8860b">?person</span> <span style="color:#00f;font-weight:bold">vcard</span>:<span style="color:#008000;font-weight:bold">FN</span> <span style="color:#b8860b">?name</span> .
</span></span><span style="display:flex;"><span> <span style="color:#a2f;font-weight:bold">OPTIONAL</span> { <span style="color:#b8860b">?person</span> <span style="color:#00f;font-weight:bold">info</span>:<span style="color:#008000;font-weight:bold">age</span> <span style="color:#b8860b">?age</span> . <span style="color:#a2f;font-weight:bold">FILTER</span> ( <span style="color:#b8860b">?age</span> <span style="color:#666">&gt;</span> <span style="color:#666">24</span> ) }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>So, if we filter for ages greater than 24 in the optional part, we
will still get 4 solutions (from the <code>vcard:FN</code> pattern) but only
get ages if they pass the test.</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-turtle" data-lang="turtle"><span style="display:flex;"><span><span style="">-----------------------</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">|</span><span style="color:#bbb"> </span><span style="">name</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb"> </span><span style="">age</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">=======================</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">|</span><span style="color:#bbb"> </span><span style="color:#b44">&#34;Becky Smith&#34;</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">|</span><span style="color:#bbb"> </span><span style="color:#b44">&#34;Sarah Jones&#34;</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">|</span><span style="color:#bbb"> </span><span style="color:#b44">&#34;John Smith&#34;</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb"> </span><span style="color:#666">25</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">|</span><span style="color:#bbb"> </span><span style="color:#b44">&#34;Matt Jones&#34;</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">-----------------------</span><span style="color:#bbb">
</span></span></span></code></pre></div><p>No age included for &ldquo;Becky Smith&rdquo; because it is less than 24.</p>
<p>If the filter condition is moved out of the optional part, then it
can influence the number of solutions, but it may be necessary to
make the filter more complicated to allow for variable <code>age</code> being
unbound (<a href="sparql_data/q-opt4.rq">q-opt4.rq</a>).</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sparql" data-lang="sparql"><span style="display:flex;"><span><span style="color:#a2f;font-weight:bold">PREFIX</span> <span style="color:#00f;font-weight:bold">info</span>: <span style="color:#a0a000">&lt;http://somewhere/peopleInfo#&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#a2f;font-weight:bold">PREFIX</span> <span style="color:#00f;font-weight:bold">vcard</span>: <span style="color:#a0a000">&lt;http://www.w3.org/2001/vcard-rdf/3.0#&gt;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a2f;font-weight:bold">SELECT</span> <span style="color:#b8860b">?name</span> <span style="color:#b8860b">?age</span>
</span></span><span style="display:flex;"><span><span style="color:#a2f;font-weight:bold">WHERE</span>
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span> <span style="color:#b8860b">?person</span> <span style="color:#00f;font-weight:bold">vcard</span>:<span style="color:#008000;font-weight:bold">FN</span> <span style="color:#b8860b">?name</span> .
</span></span><span style="display:flex;"><span> <span style="color:#a2f;font-weight:bold">OPTIONAL</span> { <span style="color:#b8860b">?person</span> <span style="color:#00f;font-weight:bold">info</span>:<span style="color:#008000;font-weight:bold">age</span> <span style="color:#b8860b">?age</span> . }
</span></span><span style="display:flex;"><span> <span style="color:#a2f;font-weight:bold">FILTER</span> ( <span style="color:#666">!</span><span style="color:#00a000">bound</span>(<span style="color:#b8860b">?age</span>) <span style="color:#666">||</span> <span style="color:#b8860b">?age</span> <span style="color:#666">&gt;</span> <span style="color:#666">24</span> )
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>If a solution has an <code>age</code> variable, then it must be greater than
24. It can also be unbound. There are now three solutions:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-turtle" data-lang="turtle"><span style="display:flex;"><span><span style="">-----------------------</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">|</span><span style="color:#bbb"> </span><span style="">name</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb"> </span><span style="">age</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">=======================</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">|</span><span style="color:#bbb"> </span><span style="color:#b44">&#34;Sarah Jones&#34;</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">|</span><span style="color:#bbb"> </span><span style="color:#b44">&#34;John Smith&#34;</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb"> </span><span style="color:#666">25</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">|</span><span style="color:#bbb"> </span><span style="color:#b44">&#34;Matt Jones&#34;</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">-----------------------</span><span style="color:#bbb">
</span></span></span></code></pre></div><p>Evaluating an expression which has an unbound variables where a
bound one was expected causes an evaluation exception and the whole
expression fails.</p>
<h2 id="optionals-and-order-dependent-queries">OPTIONALs and Order Dependent Queries</h2>
<p>One thing to be careful of is using the same variable in two or
more optional clauses (and not in some basic pattern as well):</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sparql" data-lang="sparql"><span style="display:flex;"><span><span style="color:#a2f;font-weight:bold">PREFIX</span> <span style="color:#00f;font-weight:bold">foaf</span>: <span style="color:#a0a000">&lt;http://xmlns.com/foaf/0.1/&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#a2f;font-weight:bold">PREFIX</span> <span style="color:#00f;font-weight:bold">vCard</span>: <span style="color:#a0a000">&lt;http://www.w3.org/2001/vcard-rdf/3.0#&gt;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a2f;font-weight:bold">SELECT</span> <span style="color:#b8860b">?name</span>
</span></span><span style="display:flex;"><span><span style="color:#a2f;font-weight:bold">WHERE</span>
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span> <span style="color:#b8860b">?x</span> <span style="color:#a2f;font-weight:bold">a</span> <span style="color:#00f;font-weight:bold">foaf</span>:<span style="color:#008000;font-weight:bold">Person</span> .
</span></span><span style="display:flex;"><span> <span style="color:#a2f;font-weight:bold">OPTIONAL</span> { <span style="color:#b8860b">?x</span> <span style="color:#00f;font-weight:bold">foaf</span>:<span style="color:#008000;font-weight:bold">name</span> <span style="color:#b8860b">?name</span> }
</span></span><span style="display:flex;"><span> <span style="color:#a2f;font-weight:bold">OPTIONAL</span> { <span style="color:#b8860b">?x</span> <span style="color:#00f;font-weight:bold">vCard</span>:<span style="color:#008000;font-weight:bold">FN</span> <span style="color:#b8860b">?name</span> }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>If the first optional binds <code>?name</code> and <code>?x</code> to some values, the
second <code>OPTIONAL</code> is an attempt to match the ground triples (<code>?x</code>
and <code>?name</code> have values). If the first optional did not
match the optional part, then the second one is an attempt to match
its triple with two variables.</p>
<p>With an example set of data in which every combination of values exist:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#008000;font-weight:bold">&lt;rdf:RDF</span>
</span></span><span style="display:flex;"><span> <span style="color:#b44">xmlns:rdf=</span><span style="color:#b44">&#39;http://www.w3.org/1999/02/22-rdf-syntax-ns#&#39;</span>
</span></span><span style="display:flex;"><span> <span style="color:#b44">xmlns:vCard=</span><span style="color:#b44">&#39;http://www.w3.org/2001/vcard-rdf/3.0#&#39;</span>
</span></span><span style="display:flex;"><span> <span style="color:#b44">xmlns:info=</span><span style="color:#b44">&#39;http://somewhere/peopleInfo#&#39;</span>
</span></span><span style="display:flex;"><span> <span style="color:#b44">xmlns:foaf=</span><span style="color:#b44">&#39;http://xmlns.com/foaf/0.1/&#39;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000;font-weight:bold">&gt;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#080;font-style:italic">&lt;!-- both vCard:FN and foaf:name have values, and the values are the same --&gt;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000;font-weight:bold">&lt;foaf:Person</span> <span style="color:#b44">rdf:about=</span><span style="color:#b44">&#34;http://somewhere/JohnSmith&#34;</span><span style="color:#008000;font-weight:bold">&gt;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000;font-weight:bold">&lt;vCard:FN&gt;</span>John Smith<span style="color:#008000;font-weight:bold">&lt;/vCard:FN&gt;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000;font-weight:bold">&lt;foaf:name&gt;</span>John Smith<span style="color:#008000;font-weight:bold">&lt;/foaf:name&gt;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000;font-weight:bold">&lt;/foaf:Person&gt;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#080;font-style:italic">&lt;!-- both vCard:FN and foaf:name have values, but the values are not the same --&gt;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000;font-weight:bold">&lt;foaf:Person</span> <span style="color:#b44">rdf:about=</span><span style="color:#b44">&#34;http://somewhere/RebeccaSmith&#34;</span><span style="color:#008000;font-weight:bold">&gt;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000;font-weight:bold">&lt;vCard:FN&gt;</span>Becky Smith<span style="color:#008000;font-weight:bold">&lt;/vCard:FN&gt;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000;font-weight:bold">&lt;foaf:name&gt;</span>Rebecca Smith<span style="color:#008000;font-weight:bold">&lt;/foaf:name&gt;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000;font-weight:bold">&lt;/foaf:Person&gt;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#080;font-style:italic">&lt;!-- only vCard:FN has values --&gt;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000;font-weight:bold">&lt;foaf:Person</span> <span style="color:#b44">rdf:about=</span><span style="color:#b44">&#34;http://somewhere/SarahJones&#34;</span><span style="color:#008000;font-weight:bold">&gt;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000;font-weight:bold">&lt;vCard:FN&gt;</span>Sarah Jones<span style="color:#008000;font-weight:bold">&lt;/vCard:FN&gt;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000;font-weight:bold">&lt;/foaf:Person&gt;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#080;font-style:italic">&lt;!-- only foaf:name has values --&gt;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000;font-weight:bold">&lt;foaf:Person</span> <span style="color:#b44">rdf:about=</span><span style="color:#b44">&#34;http://somewhere/MattJones&#34;</span><span style="color:#008000;font-weight:bold">&gt;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000;font-weight:bold">&lt;foaf:name&gt;</span>Matthew Jones<span style="color:#008000;font-weight:bold">&lt;/foaf:name&gt;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000;font-weight:bold">&lt;/foaf:Person&gt;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#080;font-style:italic">&lt;!-- neither vCard:FN nor foaf:name have values --&gt;</span>
</span></span><span style="display:flex;"><span> <span style="color:#008000;font-weight:bold">&lt;foaf:Person</span> <span style="color:#b44">rdf:about=</span><span style="color:#b44">&#34;http://somewhere/AdamJones&#34;</span> <span style="color:#008000;font-weight:bold">/&gt;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#008000;font-weight:bold">&lt;/rdf:RDF&gt;</span>
</span></span></code></pre></div><p>Executing the above query will yield these solutions:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-turtle" data-lang="turtle"><span style="display:flex;"><span><span style="">-------------------</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">|</span><span style="color:#bbb"> </span><span style="">name</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">===================</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">|</span><span style="color:#bbb"> </span><span style="color:#b44">&#34;John Smith&#34;</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">|</span><span style="color:#bbb"> </span><span style="color:#b44">&#34;Matthew Jones&#34;</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">|</span><span style="color:#bbb"> </span><span style="color:#b44">&#34;Sarah Jones&#34;</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">|</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">|</span><span style="color:#bbb"> </span><span style="color:#b44">&#34;Rebecca Smith&#34;</span><span style="color:#bbb"> </span><span style="">|</span><span style="color:#bbb">
</span></span></span><span style="display:flex;"><span><span style="color:#bbb"></span><span style="">-------------------</span><span style="color:#bbb">
</span></span></span></code></pre></div><p><a href="sparql_union.html">Next: union queries</a></p>
</article>
<aside class="text-muted align-self-start mb-3 mb-xl-5 p-0 d-none d-xl-flex flex-column sticky-top">
<h2 class="h6 sticky-top m-0 p-2 bg-body-tertiary">On this page</h2>
<nav id="TableOfContents">
<ul>
<li><a href="#optionals">OPTIONALs</a></li>
<li><a href="#optionals-with-filters">OPTIONALs with FILTERs</a></li>
<li><a href="#optionals-and-order-dependent-queries">OPTIONALs and Order Dependent Queries</a></li>
</ul>
</nav>
</aside>
</main>
</div>
</div>
</div>
<footer class="bd-footer py-4 py-md-5 mt-4 mt-lg-5 bg-body-tertiary">
<div class="container" style="font-size:80%" >
<p>
Copyright &copy; 2011&ndash;2024 The Apache Software Foundation, Licensed under the
<a href="https://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 src="/js/popper.min.js.js" type="text/javascript"></script>
<script src="/js/bootstrap.min.js" type="text/javascript"></script>
<script src="/js/improve.js" type="text/javascript"></script>
<script type="text/javascript">
(function() {
'use strict'
const links = document.querySelectorAll(`a[href="${window.location.pathname}"]`)
if (links !== undefined && links !== null) {
for (const link of links) {
link.classList.add('active')
let parentElement = link.parentElement
let count = 0
const levelsLimit = 4
while (['UL', 'LI'].includes(parentElement.tagName) && count <= levelsLimit) {
if (parentElement.tagName === 'LI') {
parentElement.querySelector('a:first-child').classList.add('active')
}
parentElement = parentElement.parentElement
count++
}
}
}
})()
</script>
</body>
</html>