Concept Architecture
SPARQL Queries for Health Economic Evidence and Costs
SPARQL is a query language and protocol for data held in the Resource Description Framework (RDF), the W3C graph format in which every fact is a triple made of a subject, a predicate and an object. A SPARQL query states a pattern of such facts, for instance a medicine that belongs to a drug class and appears in a cost record, and the query engine returns every way the pattern matches the data as a table, a true or false answer or a new graph. Health economists meet it wherever evidence, codes or costs are published as linked data, because one query can follow a class hierarchy, combine named sources and total the results while each fact keeps its web identifier. The current W3C Recommendations are the eleven SPARQL 1.1 documents of March 2013, and the SPARQL 1.2 Query Language is a W3C Working Draft, latest version 1 November 2026.
Triple patterns, variables and the four query forms
An RDF graph is a set of triples whose predicates are IRIs naming binary relations. Because IRIs have global scope, the same IRI in a trial extract and in a cost schedule denotes the same thing. Most SPARQL queries contain a basic graph pattern, a set of triple patterns that are like RDF triples except that the subject, predicate or object may be a variable. Each way of substituting terms from the data for the variables is one solution.
The specification defines four query forms. SELECT returns the bound variables as a table, CONSTRUCT fills a template of triples to build a new graph, ASK returns true or false, and DESCRIBE returns a graph describing the resources found. SELECT results can be exchanged as XML, JSON, CSV or TSV, so a list of unit costs can be read directly by a spreadsheet or an R script that feeds a decision model.
In an illustrative register of model inputs, each parameter is a node with a type, a value in GBP and a link to its source. The query in the table returns each outpatient cost parameter with its value.
| Query line | What it does |
|---|---|
PREFIX ex: <http://example.org/he#> | Declares a short prefix for the register's IRIs |
SELECT ?p ?v | Asks for a table with two columns |
WHERE { ?p a ex:OutpatientCost . | Matches nodes typed as outpatient costs (the keyword a stands for rdf:type) |
?p ex:value ?v . } | Binds the value attached to each matched node |
Optional facts, absent facts and the open world
A basic graph pattern rejects any solution in which part of it fails, yet regular, complete structures cannot be assumed in RDF graphs. OPTIONAL adds bindings where the data exist and keeps the solution where they do not, so a list of resource-use items still shows items lacking a unit cost. SPARQL also has two forms of negation. FILTER NOT EXISTS keeps a solution only when a given pattern has no match, and MINUS removes the solutions that are compatible with those of a second pattern.
These operators answer questions about the data, not about the world. Graph data are usually read under the open world assumption described by Hogan and colleagues, in which a missing edge leaves the relation unknown. A query that finds no trial linking two treatments shows only that the graph records none, so it cannot replace the searches of a systematic review.
Property paths through hierarchies and evidence networks
A property path is a route through the graph between two nodes, and SPARQL 1.1 lets a query match paths of any length. A path element followed by an asterisk matches zero or more steps of that predicate, a plus sign matches one or more, and a slash joins steps in sequence. The specification's own example pairs the type predicate with zero or more subclass steps to retrieve every type and supertype of a resource, the pattern needed to collect every record coded under a drug class or its subclasses.
Paths also test connectivity. Following trial and arm links one or more times shows whether two treatments never compared head to head are joined through common comparators, which is the structural question behind an indirect treatment comparison or a network meta-analysis. Connectivity matching returns each connected pair once, however many routes join them, and cycles in the graph do not lead to infinite results. A sequence path can instead return the same answer more than once through hidden intermediate nodes, as step 5 of the worked example shows.
Aggregates for counts and cost totals
Aggregates compute one value over a group of solutions. SPARQL 1.1 defines COUNT, SUM, MIN, MAX, AVG, GROUP_CONCAT and SAMPLE, and GROUP BY splits the solutions into groups, for example by cost category or by registry. This is how a query produces the totals that a budget impact analysis or a cost-of-illness study needs.
Some definitions in the specification matter for costing. COUNT counts only values that are bound and not errors, and the sum of an empty group is defined as 0, so a total of zero can mean either no spending or no matching records. A value that is not a number makes an average over its group an error, and in the specification's example that group still appears in the output with no average.
Worked example with an illustrative model input register
All names and numbers are hypothetical and illustrative. A register for a cost-effectiveness model holds four annual cost parameters per patient, each typed by category. Critical care cost is a subclass of inpatient cost, and inpatient and outpatient cost are subclasses of hospital cost.
| Parameter | Type | Value (GBP) | Source |
|---|---|---|---|
| p1 | Inpatient cost | 1,200 | Source S1 |
| p2 | Critical care cost | 2,500 | Source S2 |
| p3 | Outpatient cost | 300 | Source S1 |
| p4 | Outpatient cost | 150 | none recorded |
Step 1. A query that sums the values of nodes typed directly as hospital costs matches nothing under the default simple entailment, because no parameter carries that type itself. The sum of the empty group is 0, so the query returns GBP 0 and no error.
Step 2. Replacing the direct type with the type predicate and zero or more subclass steps reaches all four parameters. The total is
where is the annual hospital cost per patient in GBP, is the set of parameters whose type reaches the hospital cost class through zero or more subclass links, and is the value of parameter in GBP. With the four parameters,
where the terms are the values of p1, p2, p3 and p4.
Step 3. Ending the path at the inpatient class returns p1 and p2, a subtotal of GBP 3,700, because critical care sits under inpatient care.
Step 4. Adding FILTER NOT EXISTS on the source link returns p4 alone, so GBP 150 of the GBP 4,150, about 3.6%, rests on an input with no recorded source.
Step 5. If p2 is also typed as an inpatient cost, the sequence path reaches the hospital class through two type nodes, p2 appears twice and SUM returns GBP 6,650, which is GBP 2,500 too much. Selecting distinct pairs of parameter and value in a subquery before summing restores GBP 4,150.
Step 6. The queries decided which inputs entered the total and flagged one without a source. Whether GBP 2,500 is a sound estimate of critical care cost remains a question for the review of each parameter input.
Datasets, entailment and queries across services
A SPARQL query runs against an RDF dataset made of one unnamed default graph and zero or more named graphs, each identified by an IRI, and parts of a query can be matched against chosen graphs. A store can therefore keep each source, such as a unit cost schedule or a trial extract, in its own named graph, so that the origin of a value can be part of the answer.
What counts as a match also depends on the entailment regime. By default a basic graph pattern is evaluated by subgraph matching, called simple entailment, and the SPARQL 1.1 Entailment Regimes specification defines the answers when inferences under RDF Schema or OWL also count. In an example in the SPARQL 1.1 Overview, a query for labels returns nothing under simple entailment and four labels from an engine aware of RDF Schema.
The SPARQL 1.1 Protocol carries queries and updates over HTTP to a service whose address is called a SPARQL endpoint, and the Update language adds operations that change, create and remove graphs in a store. The Federated Query extension adds the SERVICE keyword, which sends part of a query to a remote endpoint and combines the results with the rest. A failed remote call normally makes the whole query fail, but with the SILENT keyword it is treated as one solution with no bindings, so results still come back without that source's data.
Documented uses in health research
Gisslander and colleagues federated six European registries of ANCA-associated vasculitis in the FAIRVASC project. Registry data were converted to RDF with the RDB to RDF Mapping Language and a shared vasculitis ontology, each registry kept its data within its own firewall behind an exposed endpoint, and aggregated patient characteristics for 5,282 cases were retrieved with SPARQL before outcome rates were pooled by random effects meta-analysis. Because the federated queries moved no subject-level data between sites, summary statistics that need the global rank of the data, such as quantiles, could not be assessed, a limit when a model needs a median or a full distribution. The authors also found that data quality varied, with completeness between 49% and 100% and correctness between 60% and 100%, and that outcome definitions differed between registries, problems that a shared query language does not resolve. Federation let each registry keep control of access rights, the data governance concern the authors give as a reason for the design.
Xiao and colleagues built FHIR-Ontop-OMOP, which exposes a relational database in the OMOP Common Data Model as a virtual knowledge graph in FHIR RDF without materialising any triples. The system translates SPARQL queries over the graph into SQL queries over the OMOP database. Five pairs of equivalent SQL and SPARQL queries over MIMIC-III data gave identical patient counts, although the authors report that some SPARQL queries were at first hard to formulate or gave different counts until implementation issues were fixed. For real-world data studies drawn from electronic health records, a paired check of this kind tests whether a graph layer has changed the cohort behind a cost or outcome estimate.
SPARQL beside SQL, Cypher and the other semantic web standards
SQL queries tables whose schema is defined in advance, while SPARQL matches graph patterns over triples that need no shared table design. Hogan and colleagues list SPARQL for RDF graphs beside Cypher, Gremlin and G-CORE for property graphs, languages that share graph patterns and path expressions but differ in how a pattern is matched, which can change a count.
Within the semantic web standards, RDF supplies the data model, the Web Ontology Language (OWL) and the Simple Knowledge Organization System (SKOS) supply classes, hierarchies and vocabularies that SPARQL can query, and the Shapes Constraint Language (SHACL) validates RDF graphs, with its SHACL-SPARQL part adding constraints written as SPARQL queries. HealthEconomics.wiki's own Health Economics Ontology (HEO) is published in SKOS and OWL with typed relationships between concepts, so a downloaded copy can be loaded into a triple store and explored with path queries. SPARQL contributes to digital interoperability because any compliant client can query any compliant endpoint and read the answer in a standard format.
Misreadings that change an analysis
Most errors come from reading query output as a statement about the world. Four recur in health economic work.
- Reading an empty result or a zero total as a finding. No match means nothing is recorded, and a mistyped class name returns a sum of 0 with no error.
- Counting a record twice through a path. Totals over hierarchies should be checked against a count of distinct records.
- Assuming two set-ups give the same answer. The entailment regime and any SILENT remote calls change what is returned, so both should be reported with the query.
- Treating a public endpoint as always available. Hogan and colleagues report that public services, most often offering SPARQL, have been found to show downtime, timeouts, partial results and slow performance, so a model input taken from a live endpoint should be saved with its query text and retrieval date.
Sources
- Cyganiak R, Wood D, Lanthaler M, editors. RDF 1.1 Concepts and Abstract Syntax. W3C Recommendation, 25 February 2014. https://www.w3.org/TR/rdf11-concepts/
- Feigenbaum L, Williams GT, Clark KG, Torres E, editors. SPARQL 1.1 Protocol. W3C Recommendation, 21 March 2013. https://www.w3.org/TR/sparql11-protocol/
- Gisslander K, Rutherford M, Aslett L, et al. Data quality and patient characteristics in European ANCA-associated vasculitis registries: data retrieval by federated querying. Annals of the Rheumatic Diseases. 2024;83(1):112-120. https://doi.org/10.1136/ard-2023-224571
- Glimm B, Ogbuji C, editors. SPARQL 1.1 Entailment Regimes. W3C Recommendation, 21 March 2013. https://www.w3.org/TR/sparql11-entailment/
- Harris S, Seaborne A, editors. SPARQL 1.1 Query Language. W3C Recommendation, 21 March 2013. https://www.w3.org/TR/sparql11-query/
- Hartig O, Seaborne A, Taelman R, Williams G, Pellissier Tanon T, editors. SPARQL 1.2 Query Language. W3C Working Draft, 1 November 2026. https://www.w3.org/TR/sparql12-query/
- Hogan A, Blomqvist E, Cochez M, et al. Knowledge graphs. ACM Computing Surveys. 2021;54(4):1-37. https://doi.org/10.1145/3447772
- Knublauch H, Kontokostas D, editors. Shapes Constraint Language (SHACL). W3C Recommendation, 20 July 2017. https://www.w3.org/TR/shacl/
- Prud'hommeaux E, Buil-Aranda C, editors. SPARQL 1.1 Federated Query. W3C Recommendation, 21 March 2013. https://www.w3.org/TR/sparql11-federated-query/
- W3C SPARQL Working Group. SPARQL 1.1 Overview. W3C Recommendation, 21 March 2013. https://www.w3.org/TR/sparql11-overview/
- Xiao G, Pfaff E, Prud'hommeaux E, et al. FHIR-Ontop-OMOP: building clinical knowledge graphs in FHIR RDF with the OMOP Common Data Model. Journal of Biomedical Informatics. 2022;134:104201. https://doi.org/10.1016/j.jbi.2022.104201
Related Concepts (3)
Frequently Asked Questions (6)
What is SPARQL?
SPARQL is the W3C query language and protocol for RDF graphs, used in health economics to retrieve linked facts such as trial arms, codes and unit costs.
Source: W3C 2013
How does a SPARQL property path collect every cost record coded under a drug class or its subclasses?
A property path is a route through the graph between two nodes, and SPARQL 1.1 lets a query match paths of any length. An asterisk after a path element matches zero or more steps of that predicate, and a slash joins steps in sequence. The specification's own example joins the type predicate to zero or more subclass steps to retrieve every type and supertype of a resource, so records typed under a narrower class are reached along with those typed under the class itself. A sequence path can still return one record more than once through hidden intermediate nodes, so totals over a hierarchy are best checked against a count of distinct records.
Source: W3C 2013
Why can an empty result or a zero total from a SPARQL query mislead a cost analysis?
The SPARQL 1.1 Query Language defines the sum of an empty group as 0, so a query that matches nothing returns a total of zero and no error. A mistyped class name produces this result, as does a query for a class that no record carries directly when the default simple entailment is used. COUNT counts only values that are bound and not errors, so a count can also fall short of the records held. A zero total can therefore mean either no spending or no matching records, and the class names and the entailment regime should be checked before it is read as a finding.
Source: W3C 2013
How does SPARQL differ from SQL and Cypher when querying health data?
Hogan and colleagues contrast the relational model, in which a schema must be defined in advance, with graph data, which need no shared table design. SPARQL matches graph patterns over RDF triples, while SQL queries tables. Cypher, Gremlin and G-CORE are the corresponding languages for property graphs, and they share graph patterns and path expressions with SPARQL. The languages differ in how a pattern is matched, because SPARQL lets several variables map to the same term while Cypher requires distinct edges, so the same pattern can return a different count in each. Results from a query moved between these languages therefore need to be checked again.
Source: Hogan et al. 2021
How was SPARQL used to federate European vasculitis registries in the FAIRVASC project?
Gisslander and colleagues linked six European registries of ANCA-associated vasculitis by converting their data to RDF with the RDB to RDF Mapping Language and a shared vasculitis ontology. Each registry kept its data within its own firewall and exposed an endpoint, and aggregated patient characteristics for 5,282 cases were retrieved with SPARQL before outcome rates were pooled by random effects meta-analysis. Because no subject-level data moved between sites, statistics that need the global rank of the data, such as quantiles, could not be assessed. Completeness ranged from 49% to 100% and outcome definitions differed between registries, problems that a shared query language does not resolve.
Source: Gisslander et al. 2024
What should be recorded when a model input is taken from a public SPARQL endpoint?
Hogan and colleagues report that public query services, most often offering SPARQL, have been found to show downtime, timeouts, partial results and slow performance. A value retrieved on one day may therefore be missing or incomplete when the same query is run again. The query text and the date of retrieval should be saved with any model input taken from a live endpoint, so that a reviewer can rerun the query and see whether the answer has changed. The saved result also keeps the input fixed for the decision model, whatever later happens to the service.
Source: Hogan et al. 2021
Trust Record
Verified by Dr Darrin Baines
British health economist
Professional identity: darrinbaines.org
Verification date: 2 Nov 2026
Content version: 1.0.2
Canonical Identity
- Persistent URI
- https://healtheconomics.wiki/concept/sparql
- Term code
- HS-HP-DH-051
Stable URI · Machine-readable · Resolvable · CC BY 4.0
