Nikolai showed a draft MaterializedView resource, and the group warmed to building data quality checks on top of SQL on FHIR.
Several speakers
6 presenters
Weekly meetings of the HL7 SQL on FHIR working group — spec discussions, implementer demos, and open design questions. Recordings are public; no registration needed.
120 talks
Nikolai showed a draft MaterializedView resource, and the group warmed to building data quality checks on top of SQL on FHIR.
Several speakers
6 presenters
Evan Machusak walked the group through compiling CQL into SQL, and why writing measures one patient at a time is what makes them slow.
Several speakers
5 presenters
Whether materialise should be a resource or just operations, three spec PRs reviewed, and the ballot notice going in.
Several speakers
5 presenters
John Grimes walked through the merged inter-query dependencies, and Steve Munini's six consistency fixes opened up the FHIR async mess.
Several speakers
4 presenters
John Grimes moved the spec into an HL7 repo, and the group argued out whether a SQL view deserves a profile of its own.
Several speakers
4 presenters
Nikolai Ryzhikov demoed FHIR-to-OMOP and the reason it's hard: one Condition can land in three tables, and the terminology decides which.
Several speakers
3 presenters
Nikolai Ryzhikov showed an early FHIR-to-OMOP prototype, and John Grimes warned that shipping a rival mapping would just make enemies.
Several speakers
4 presenters
A thin week: Craig McClendon, Steve Munini and Arjun Sanyal compared two ways to flatten FHIR, and what each one costs you later.
Several speakers
3 presenters
Ilya Korover demoed a data governance layer over SQL on FHIR that traces every column back to the FHIRPath it came from.
Several speakers
6 presenters
With most of the group away, John Grimes made the case that the way to spread SQL on FHIR is a slow, naive implementation inside HAPI.
Several speakers
5 presenters
Nikolai Ryzhikov pitched a dbt-style DAG of queries, and Gino Canessa asked whether `dependsOn` is even the right word for it.
Several speakers
6 presenters
Nikolai Ryzhikov said quality measures look better in OMOP; Gino Canessa pushed back that OMOP's modelling bets are why SQL on FHIR exists.
Several speakers
6 presenters
Should SQL on FHIR bolt onto CQL's evaluate operation, or is the Measure resource far more machinery than anyone needs?
Key-values nested inside key-values for $run parameters, and nobody has a good answer for authorising an arbitrary SQL query.
A payer explains why claims data can never answer a seven-day follow-up question, and what he wants from FHIR instead.
Where the human-readable SQL goes, which dialect you're in, and why rowIndex can't just be FHIRPath's $index.
If an agent writes your ViewDefinitions, how do you know they're any good? The group went hunting for a gold standard.
Why $export hands back a 303 instead of the result, and who is actually going to write the queries once the FHIR data arrives.
join on an empty collection: FHIRPath says empty, the SQL on FHIR tests say empty string, and fixing it breaks implementations.
Arjun Sanyal spent an open session making the economic case for FHIR analytics: a standard that raises your costs is a terrible sales pitch.
Several speakers
4 presenters
John Grimes walked through the project scope statement that turns SQL on FHIR into an official HL7 project, with a September ballot in view.
Several speakers
4 presenters
Nikolai Ryzhikov argued the async draft is half hypermedia and half convention, and gets the worst of both.
Several speakers
3 presenters
John Grimes argued that turning a clinical guideline into computable criteria quietly deletes the nuance clinicians were actually applying.
Several speakers
3 presenters
Gino Canessa explained why reporting a failed job as an HTTP error breaks HTTP — and quietly breaks somebody's error budget.
Several speakers
5 presenters
Nikolai Ryzhikov pushed back on the draft async pattern: why make a client fetch the result just to find out the job failed?
Several speakers
5 presenters
Eugene Vestel pitched compiling CQL into ViewDefinitions plus plain SQL — and John Grimes noted the most common CQL engine today is still a ...
Several speakers
4 presenters
John Grimes made the case for HL7 bureaucracy: the group runs loose enough that decisions get made without the people who would have objecte...
Several speakers
3 presenters
Why ViewDefinition can't simply be declared a FHIR resource, and a repeat directive for data that nests all the way down.
Gino Canessa explained what it takes for ViewDefinition to become a real FHIR resource, and why HL7 has to own the short name.
Several speakers
6 presenters
The group gave up on making ViewDefinition work properly in R4 and aimed at R6, and John Grimes demoed a SQL on FHIR runner for SQL Server.
Several speakers
4 presenters
Nikolai argued backport IGs may cost the ecosystem more than they're worth, and that SQL on FHIR should live outside the FHIR core for good.
Several speakers
4 presenters
Nikolai and Arjun agreed the first API release ships R4-compatible, on the reasoning that R4 is what people will actually run for years yet.
Several speakers
2 presenters
John Grimes wants to count a cohort before extracting it. Every obvious way of doing it breaks, so he's betting on a FHIRPath search paramet...
Several speakers
3 presenters
The group settled on targeting R4 with system-level operations, and John Grimes explained why a `repeat` directive needs a `repeatOrNull` tw...
Several speakers
5 presenters
Gene Vestel demoed translating CQL measures into SQL on FHIR, and Nikolai pitched an API for keeping a view materialised and up to date.
Several speakers
4 presenters
Brian Kaney and Nikolai went looking for a way to point a ViewDefinition at a questionnaire, and found FHIR's own answer already sitting the...
Several speakers
5 presenters
How a ViewDefinition points back at the questionnaire it was built for, and why it can't be a typed operation parameter in R4.
Gino Canessa explained why ViewDefinition can't be a proper resource in R4, and why every workaround costs more than just moving to R6.
Several speakers
4 presenters
Steve Munini demoed a Rust SQL on FHIR runner that passes the whole test suite, and the group spent the rest of the hour arguing about names...
Several speakers
5 presenters
Brian Kaney argued the base64 objection to Library is a red herring — nobody edits SQL inside JSON anyway — and largely won the room.
Several speakers
6 presenters
John Grimes argued for default type hints so two runners produce columns you can run the same SQL over; Nikolai Ryzhikov talked him round on...
Several speakers
6 presenters
Nikolai Ryzhikov walked through the $export draft, and the group spent most of the hour working out what _count should actually count.
Several speakers
5 presenters
John Grimes proposed proving the query resource the way view definitions were proved: run the same SQL on four engines and check the answers...
Several speakers
3 presenters
Eugene Vestel demoed a tool that builds ViewDefinitions straight from IG profiles, and Arjun Sanyal brought a third draft of the query resou...
Several speakers
9 presenters
Where should a SQL query live — inside the clinical-reasoning Library machinery, or in something small of its own?
Arjun Sanyal made the case for packing SQL into a FHIR Library; Gino Canessa and Nikolai Ryzhikov each turned up with a rival sketch.
Several speakers
6 presenters
Graham Grieve asked whether you can put a SQL statement into the FHIR search API; Gino Canessa said not raw SQL, and offered named queries i...
Several speakers
5 presenters
John Grimes brought a list of holes in the FHIRPath subset, starting with the fact that the test suite doesn't obey the subset it is testing...
Several speakers
5 presenters
Nikolai Ryzhikov floated a $materialise operation — tell the server to keep a view up to date elsewhere — and Steve Munini said why that get...
Several speakers
3 presenters
Gino Canessa introduced the feature-query IG, built after years of failing to rebuild the capability statement, as how a server says what it...
Several speakers
5 presenters
Nikolai Ryzhikov and John Grimes went round and round on how a client is meant to find out what a server can do, and FHIR had no good answer...
Several speakers
3 presenters
Nikolai Ryzhikov showed a client that builds its own forms out of the OperationDefinition, so the API describes itself instead of being writ...
Several speakers
3 presenters
Bartek demoed FHIRboard, which groups ViewDefinitions into an "analytical case", and John Grimes explained why he points an LLM at SQL inste...
Several speakers
3 presenters
Splitting $run from $evaluate, and a hard look at why FHIR versions can't be mapped mechanically.
Gino Canessa argued for splitting run and evaluate into two operations, and filed a FHIR ticket mid-call rather than trust himself to rememb...
Several speakers
5 presenters
How do you describe an operation whose answer is a CSV file? FHIR makes you say it returns a Binary, and nobody actually does.
Gino Canessa walked the group through how you describe an operation's input and output in FHIR, and where that approach quietly stops workin...
Several speakers
4 presenters
A reference server for the API, built to force the design questions out into the open — and they came out fast.
Nikolai Ryzhikov started writing the reference server instead of the spec, and the questions it threw up ran the rest of the meeting.
Several speakers
4 presenters
Arjun Sanyal sketched a query resource and the portable analytic it might sit inside; Steve Munini said his team keeps running into the same...
Several speakers
2 presenters
Is plain SQL over raw Parquet a goal or not — plus a first pass at packaging and executing ViewDefinitions the FHIR way.
Nikolai Ryzhikov laid out five use cases an API would have to serve, and Brian Kaney showed a rival sketch built on CRMI packaging.
Several speakers
6 presenters
DuckDB benchmarks over Parquet that came out oddly flat, and what happens when a query asks for a field the schema doesn't have.
Dan Gottlieb brought DuckDB numbers that surprised everyone: 75GB of NDJSON queried in about the same time as 100MB of Parquet.
Several speakers
5 presenters
John Grimes showed a Parquet file built from FHIR JSON with no structure definitions involved, and Bashir asked what Parquet on FHIR is actu...
Several speakers
4 presenters
Three Parquet-for-FHIR schemas compared, and the case for not fixing your schema in advance.
John Grimes diffed three ways of putting FHIR into Parquet — Pathling, FHIR Data Pipes and the new spec — and made the case against one gian...
Several speakers
4 presenters
Nikolai Ryzhikov walked his draft export API past Dan Gottlieb, who could say exactly which parts of bulk export he'd do differently today.
Several speakers
5 presenters
Designing the bulk export operation: one view or many, files or tables, and why streaming keeps turning back into subscriptions.
Dan Gottlieb argued that handing back files and maintaining a table on the server are two different operations, not one operation with a par...
Several speakers
5 presenters
A demo of using ViewDefinitions to measure how differently hundreds of payers fill in their FHIR, plus a first pass at what an API is for.
The 2025 work streams, a first sketch of a query resource, and how much of the IG integration the publisher already does.
Carving next year into work streams, and the rule that nothing gets specified without a real implementation running beside it.
How to actually publish a release of the IG, and whether a spec that promises not to break needs versioning at all.
A DuckDB evaluation: quick on flat data, five to ten times slower once lateral joins appear, and schema inference you can't lean on.
Cutting the last change down to a single link so v2 can ship, and what SQL on FHIR would add to a FHIR-to-OMOP conversion.
The second sitting of the Milestone 1 agenda, opening on what Delta Lake and Iceberg actually add on top of Parquet.
Closing out Milestone 1, and why the FHIRPath subset belongs in a shareable profile rather than in the base spec.
Part of the normative spec points at an unreleased FHIRPath build, and the group decided to stop doing that before tagging a version.
A proposal for a Parquet schema that fits the data instead of trying to cover all of FHIR, and what that pushes onto the view runner.
Two implementations: 250 lines of TypeScript typed straight from the spec's pseudocode, and a team that gave up on Parquet for Redshift.
A draft Parquet spec that derives the schema from the data, and why FHIR to OMOP is a join of two views rather than a cleverer ViewDefinitio...
What API a ViewDefinition builder needs, whether CRMI applies once ViewDefinition is canonical, and keeping the spec's informal voice.
Whether SQL on FHIR needs full FHIRPath, the view runner already inside the IG publisher, and picking a real dataset to test against.
A push for full FHIRPath with resolve(), a view runner already shipping inside the IG publisher, and MIMIC-IV as a real dataset to test on.
A decimal limit in JavaScript that the group decided not to work around, and why sorting a ViewDefinition makes no sense.
The Parquet session: three different jobs people want Parquet for, why a lossless FHIR schema gets enormous, and two ways to handle extensio...
Why a decimal test cannot assert integer, which FHIR versions are safe to declare, and the case for standardising a lossless Parquet before ...
Shareable and tabular ViewDefinition profiles, a FHIRPath bug found by a newcomer, and why the FHIR version question was really about FHIRPa...
Boundary functions missing from the JavaScript FHIRPath engine, what sibling selects actually cross join, and a C++ view runner built on sim...
Type assertions the reference implementation cannot enforce, why JSON became the source of truth for tests, and schema output from view runn...
FHIR to OMOP — integer person IDs, the missing standard concepts, and whether ViewDefinitions or plain SQL should finish the transform.
A shareable ViewDefinition profile that makes column types required, and a second profile for views that map straight to CSV.
Labelling a ViewDefinition with its intent — an enum on the resource or a FHIR profile — and what a view runner should tell you besides rows...
A test runner driven straight from JSON, the column ordering resolution, and cutting the spec back to background plus one normative section.
Should one ViewDefinition cover several resource types? Plus column ordering in the tests, and what `where` should do with an empty result.
Cutting the data layer guidance out of the core spec, and whether `ofType` with a bogus type should fail or quietly return null.
Roadmap — publish what already exists as v1, hand a ViewDefinition to bulk export, and split FHIR-on-Parquet out into its own spec.
A walkthrough of compiling a ViewDefinition into SQL, and four implementations disagreeing about how to avoid grinding to a halt.
Treating every ViewDefinition node as a function, and the edge cases the tests keep dragging into the open.
Should a ViewDefinition state its column types, or should every implementation be expected to infer them?
Freezing the feature list for a first release, why it will be called 2.0 rather than 1.0, and where the spec stops.
Why FHIR-to-OMOP is not a mechanical mapping, and whether niche use cases should be allowed to shape the spec.
Recursive data with no known depth, four ways to handle it, and a use case for resolve that has nothing to do with analytics.
Why `alias` went back to being `name`, and pinning down what a union actually means when its branches disagree.
FTR, a git-like format for shipping expanded value sets, plus a first cut of the spec as a real HL7 implementation guide.
Value sets in ViewDefinitions — a memberOf demo over a flat expansion table, and whether `where` belongs in three places at once.
Flooring a partial date into an instant, and the objection that erasing precision quietly breaks quality measures.
Someone six weeks into FHIR built two views and joined them — and forEachOrNull finally got its name.
forEach lands as an inner join by default, and nobody can name the version that keeps the row when there's nothing there.
A walkthrough of FQL, whose nested selects made the group's own variables section look unnecessary.
The first draft spec, and test cases showing that nobody agrees what two unnests next to each other should mean.
A view definition running in a browser over NDJSON, and the problem that you can't compile FHIRPath without knowing FHIR.
How to write a flattened view down — arrays or extra rows — and whether it should be a StructureDefinition or just some JSON.
UUIDs as join keys, whether versioned references matter, and pinning down the smallest set of transformations everyone needs.
The first sketch of a layered design: normalise a few things everywhere, then define flattened views on top of that with FHIRPath.
Google's FHIRPath-to-SQL work lands on the table, and the goal shifts from querying FHIR in ANSI SQL to describing flattened views.
A playground for running one query across several databases, and a hard argument about whether a macro layer is just a new SQL dialect.
A demo of getting FHIR into Spark, DuckDB, ClickHouse and DataFusion through Parquet, and a case for SQL on FHIR in low-resource clinics.
The group's first call: introductions, and the question of whether the columnar and JSON takes on SQL on FHIR can become one spec.